Tree-like array (bit,binary Indexed trees)
Let's start with a classic picture. (also stolen, address, see Watermark.)
The following transfers are from: http://blog.csdn.net/lawrence_jang/article/details/8054173
1. Single point increment + interval sum
Idea: C[x] represents the element of the point: Sum (x) =c[1]+c[2]+ ... C[X]
int ARR[MAXN]; int sum (int x) {int res=0; while (x) res+=arr[x],x-=lowbit (x); return Res;} void Add (int x,int n) {while (X<MAXN) arr[x]+=n,x+=lowbit (x);} int query (int x,int y) {return sum (y)-sum (x1
2. Interval increment + single point query
Idea: C[x] represents the difference between the point element and the left element: num[x]=c[1]+c[2]+ ... C[X]
int ARR[MAXN] int sum (int x) {int res=0; while (x) res+=arr[x],x-=lowbit (x); return Res;} void Add (int x,int n) {while (X<MAXN) arr[x]+=n,x+=lowbit (x);} int update (int x,int y,int n) {Add (x,n); Add (y+1,-n);}
3. Interval increment + interval query
Idea: C[x] Indicates the difference between the point element and the left
SUM (SUM (c[j],j<=i) i<=x) = x*c[1]+ (x-1) *c[2]+......+c[x] = (x+1) *sum (c[i],i<=x)-sum (i*c[i],i<=x);
You can think of the value of maintaining c[x] with c1[x], c2[x] The value of maintaining x*c[x]
structtree_array{structtree_array_single{intARR[MAXN]; voidAddintXintV) { while(x <= N) arr[x] + = V, x + =lowbit (x);} intSumintx) {intsum =0; while(x) sum+=arr[x], x-=lowbit (x);returnsum;} } T1, T2; voidReset () {memset (T1.arr,0,sizeofT1.arr); memset (T2.arr,0,sizeofT2.arr); } voidAddintXintV) {t1.add (x, v); T2.add (x, x*v); } voidUpdateintLintRintV) {Add (L, v); Add (r+1,-V); }//[L,r] Each point value is increased by V intSumintx) {return(x+1) *t1.sum (x)-t2.sum (x); }//the number of the first X and intQueryintLintR) {returnSUM (R)-sum (l1); }//interval [l,r] and};
4. Two dimensions: Single point increment (add) + Rectangle summation (query) + Rectangle increment (update) + Single point evaluation (sum)
intARR[MAXN][MAXN] InlinevoidAddintXintYintv) { for(inti=x;i<maxn;i+=lowbit (i)) for(intj=y;j<maxn;j+=Lowbit (j)) Arr[i][j]+=v;} InlineintSumintXinty) { intres=0; for(inti=x;i;i-=lowbit (i)) for(intj=y;j;j-=Lowbit (j)) Res+=Arr[i][j]; returnRes;} InlineintQueryintLintBintRintT) {returnSUM (r,t) +sum (l1B1)-sum (r,b-1)-sum (l1, T);} InlinevoidUpdateintLintBintRintTintV) {//The value to increase on the lower left rightAdd (L,B,V); Add (l,t+1, v); Add (r+1, b,v); Add (r+1, t+1, v);}
5. Single point increment (add) + Cube summation (query) + cube increment (update) + Single point evaluation (sum)
intARR[MAXN][MAXN][MAXN]; InlineintSumintXintYintz) { intres=0; for(inti=x;i;i-=lowbit (i)) for(intj=y;j;j-=Lowbit (j)) for(intk=z;k;k-=Lowbit (k)) Res^=Arr[i][j][k]; returnRes; } InlinevoidAddintXintYintZintv) { for(inti=x;i<maxn;i+=lowbit (i)) for(intj=y;j<maxn;j+=Lowbit (j)) for(intk=z;k<maxn;k+=Lowbit (k)) Arr[i][j][k]+=v; } InlinevoidUpdateintX1,intY1,intZ1,intX2,intY2,intZ2,intv) {Add (X1,Y1,Z1,V); Add (x2+1, y1,z1,-v); Add (x1,y2+1, z1,-v); Add (x1,y1,z2+1,-v); Add (x2+1, y2+1, z1,v); Add (x2+1, y1,z2+1, v); Add (x1,y2+1, z2+1, V); Add (x2+1, y2+1, z2+1,-v);} InlineintQueryintX1,intY1,intZ1,intX2,intY2,intZ2) { returnsum (X2,Y2,Z2)-sum (x2,y2,z1-1)-sum (x2,y1-1, Z2)-sum (x1-1, Y2,Z2)+sum (x2,y1-1, z1-1) +sum (x1-1, y2,z1-1) +sum (x1-1, y1-1, Z2)-sum (x1-1, y1-1, z1-1); }
6.RMQ
Inlinevoidinit () {memset (arr),0,sizeofarr); for(intI=1; i<=n;++i) for(intj=i;j<=n&&arr[j]<num[i];j+=Lowbit (j)) Arr[j]=Num[i]; } InlineintQueryintLintR) {intres=0; for(--l; l<R;) {if(R-lowbit (R) >=l) {Res=max (res,arr[r]); U-zlowbit (R);} Else{Res=max (res,num[r]);--R;} } returnRes; } InlinevoidUpdateintXintval) { intOri=Num[x]; NUM[X]=Val; if(val>=Ori) for(inti=x;i<=n&&arr[i]<val;i+=lowbit (i)) Arr[i]=Val; Else{ for(inti=x;i<=n&&arr[i]==ori;i+=lowbit (i)) {Arr[i]=Val; for(intJ=lowbit (i) >>1; j;j>>=1) Arr[i]=max (arr[i],arr[i-J]); } } }
Some applications of the [go] tree array