证明什么的待补
一维
#pragma GCC optimize(2) #pragma GCC optimize(3) #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+7; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll a[N],c[N],n; inline int lowbit(int x){ return x&-x; } inline void add(int i,int x){ while(i<=n){ c[i]+=x; i+=lowbit(i); } return ; } inline ll sum(int i){ ll res=0; while(i){ res+=c[i]; i-=lowbit(i); } return res; } int main(){ int q; n=read();q=read(); for(int i=1;i<=n;i++){ int x; x=read(); add(i,x); } while(q--){ int l,r,w; w=read();l=read();r=read(); if(w==1) add(l,r); else { ll res=sum(r)-sum(l-1); printf("%lld\n",res); } } return 0; }
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+7; ll a[N],c[N];//原数组和树状数组 ll n; inline ll read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline ll lowbit(ll x){ return x&-x; } void add(ll i,ll k){ while(i<=n){ c[i]+=k; i+=lowbit(i); } } ll sum(ll i){//求a[1]到a[n]的和 ll res=0; while(i>0){ res+=c[i]; i-=lowbit(i); } return res; } int main(){ ll q,x; n=read();q=read(); for(ll i=1;i<=n;i++){ a[i]=read(); add(i,a[i]-a[i-1]); } while(q--){ ll a,b,c,d; a=read(); if(a==1){ b=read();c=read();d=read(); add(b,d); add(c+1,-d); } else{ b=read(); printf("%lld\n",sum(b)); } } return 0; }
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e6+7; ll a[N],sum1[N],sum2[N]; ll n,m; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline ll lowbit(ll x){ return x&-x; } inline void update(ll i,ll k){ ll x=i; while(i<=n){ sum1[i]+=k; sum2[i]+=k*(x-1); i+=lowbit(i); } } inline ll sum(int i){ ll res=0,x=i; while(i>0){ res+=x*sum1[i]-sum2[i]; i-=lowbit(i); } return res; } int main(){ n=read();m=read(); for(ll i=1;i<=n;i++){ cin>>a[i]; update(i,a[i]-a[i-1]); } while(m--){ ll k,l,r,x; k=read(); if(k==1){ l=read();r=read();x=read(); update(l,x); update(r+1,-x); } else{ l=read();r=read(); ll res=sum(r)-sum(l-1); printf("%lld\n",res); } } return 0; }
二维
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=5500; ll a[N][N],n,m; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } ll lowbit(ll x){ return x&-x; } void update(ll x,ll y,ll v){ for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=m;j+=lowbit(j)) a[i][j]+=v; } ll sum(ll x,ll y){ ll res=0; for(int i=x;i>0;i-=lowbit(i)) for(int j=y;j>0;j-=lowbit(j)) res+=a[i][j]; return res; } ll query(ll x1,ll y1,ll x2,ll y2){ return sum(x1,y1)-sum(x1,y2-1)-sum(x2-1,y1)+sum(x2-1,y2-1); } int main(){ while(~scanf("%d%d",&n,&m)){ memset(a,0,sizeof a); int op; while(~scanf("%d",&op)){ if(op==1){ ll x,y,k; x=read();y=read();k=read(); //cin>>x>>y>>k; update(x,y,k); } else{ ll a,b,c,d; c=read();d=read();a=read();b=read(); //cin>>a>>b>>c>>d; printf("%lld\n",query(a,b,c,d)); } } } return 0; }
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2100; ll t1[N][N],t2[N][N],t3[N][N],t4[N][N]; ll n,m; ll lowbit(ll x){ return x&(-x); } void add(ll x,ll y,ll v){ for(ll i=x;i<=n;i+=lowbit(i)) for(ll j=y;j<=m;j+=lowbit(j)){ t1[i][j]+=v; t2[i][j]+=v*x; t3[i][j]+=v*y; t4[i][j]+=v*x*y; } } void update(ll x1,ll y1,ll x2,ll y2,ll v){ add(x1,y1,v); add(x1,y2+1,-v); add(x2+1,y1,-v); add(x2+1,y2+1,v); } ll sum(ll x,ll y){ ll res=0; for(ll i=x;i>0;i-=lowbit(i)) for(ll j=y;j>0;j-=lowbit(j)) res+=(x+1)*(y+1)*t1[i][j]-(y+1)*t2[i][j]-(x+1)*t3[i][j]+t4[i][j]; return res; } ll query(ll x1,ll y1,ll x2,ll y2){ return sum(x2,y2)+sum(x1-1,y1-1)-sum(x2,y1-1)-sum(x1-1,y2); } int main(){ scanf("%lld%lld", &n, &m); int op; while(~scanf("%d",&op)){ if(op==1){ ll a,b,c,d,x; scanf("%lld%lld%lld%lld%lld", &a, &b, &c, &d, &x); // a=read();b==read();c=read();d=read();x=read(); update(a,b,c,d,x); } else{ ll a,b,c,d; scanf("%lld%lld%lld%lld", &a, &b, &c, &d); //a=read();b==read();c=read();d=read(); printf("%lld\n",query(a,b,c,d)); } } return 0; }
参考博客:树状数组详解 - Xenny - 博客园 (吹爆这篇!)