树状数组模板(转) 树状数组模板区间更新 区间询问

https://blog.csdn.net/lawrence_jang/article/details/8054173





树状数组模板区间更新 区间询问


14、树状数组
(1)、单点增减+区间求和
思路:C[x]表示该点的元素:sum(x)=C[1]+C[2]+……C[x]


  
  
  1. int arr[MAXN];
  2. inline int sum(int x){ int res= 0; while(x)res+=arr[x],x-=lowbit(x); return res;}
  3. inline void add(int x,int n){ while(x<MAXN)arr[x]+=n,x+=lowbit(x);}
  4. inline int query(int x,int y){ return sum(y)-sum(x -1);}

(2)、区间增减+单点查询
思路:C[x]表示该点元素与左边元素的差值:num[x]=C[1]+C[2]+……C[x]

  
  
  1. int arr[MAXN]
  2. inline int sum(int x){ int res= 0; while(x)res+=arr[x],x-=lowbit(x); return res;}
  3. inline void add(int x,int n){ while(x<MAXN)arr[x]+=n,x+=lowbit(x);}
  4. inline int update(int x,int y,int n){add(x,n);add(y+ 1,-n);}


(3)、区间增减+区间查询
思路:C1[x]表示该点元素与左边的差值,C2[x]表示的是x*C[x]

  
  
  1. sum(sum(C[j],j<=i)i<=x)
  2. = x*C[ 1]+(x -1)*C[ 2]+……+C[x]
  3. =(x+ 1)*sum(C[i],i<=x)-sum(i*C[i],i<=x);


则可以想到用C1[x]维护C[x]的值,C2[x]维护x*C[X]的值

  
  
  1. template < typename X>
  2. struct tree_array{
  3. struct tree_array_single{
  4. X arr[MAXN];
  5. void add(int x,X n){ while(x<=N)arr[x]+=n,x+=lowbit(x);}
  6. X sum(int x){X sum= 0; while(x)sum+=arr[x],x-=lowbit(x); return sum;}
  7. }T1,T2;
  8. void reset(){CLR(T1.arr, 0); CLR(T2.arr, 0);}
  9. void add(int x,X n){T1.add(x,n);T2.add(x,x*n);}
  10. void update(int L,int R,int n){add(L,n);add(R+ 1,-n);}
  11. X sum(int x){ return (x+ 1)*T1.sum(x)-T2.sum(x);}
  12. X query(int L,int R){ return sum(R)-sum(L -1);}
  13. };


15、多维树状数组
①单点增减(add) + 矩形求和(query) 
②矩形增减(update) + 单点求值(sum)

  
  
  1. int arr[MAXN][MAXN]
  2. inline void add(int x,int y,int n) {
  3. for( int i=x;i<MAXN;i+=lowbit(i))
  4. for( int j=y;j<MAXN;j+=lowbit(j))
  5. arr[i][j]+=n;
  6. }
  7. inline int sum(int x,int y){
  8. int res= 0;
  9. for( int i=x;i;i-=lowbit(i))
  10. for( int j=y;j;j-=lowbit(j))
  11. res+=arr[i][j];
  12. return res;
  13. }
  14. inline int query(int L,int B,int R,int T) {
  15. return sum(R,T)+sum(L -1,B -1)-sum(R,B -1)-sum(L -1,T);
  16. }
  17. inline void update(int L,int B,int R,int T,int n){
  18. update(L,B,n);update(L,T+ 1,n);update(R+ 1,B,n);update(R+ 1,T+ 1,n);
  19. }


③矩形增减(update)+ 矩形求和(query)

  
  
  1. template< typename X>
  2. class tree_array{
  3. struct tree_array_single{
  4. X arr[MAXN][MAXN];
  5. void add(int x,int y,X n){
  6. for( int i=x; i<MAXN; i+=lowbit(i))
  7. for( int j=y; j<MAXN; j+=lowbit(j))
  8. arr[i][j]+=n;
  9. }
  10. X sum(int x,int y){
  11. X res= 0;
  12. for( int i=x; i; i-=lowbit(i))
  13. for( int j=y; j; j-=lowbit(j))
  14. res+=arr[i][j];
  15. return res;
  16. }
  17. } T1,T2,T3,T4;
  18. void add(int x,int y,int n){
  19. T1.add(x,y,n);T2.add(x,y,y*n);T3.add(x,y,x*n);T4.add(x,y,x*y*n);
  20. }
  21. X sum(int x,int y){
  22. return (x+ 1)*(y+ 1)*T1.sum(x,y)-(x+ 1)*T2.sum(x,y)-(y+ 1)*T3.sum(x,y)+T4.sum(x,y);}
  23. public:
  24. void init(){CLR(T1.arr, 0);CLR(T2.arr, 0);CLR(T3.arr, 0);CLR(T4.arr, 0);}
  25. void update(int L,int B,int R,int T,int n){
  26. add(L,B,n);add(L,T+ 1,-n);add(R+ 1,B,-n);add(R+ 1,T+ 1,n);
  27. }
  28. X query(int L,int B,int R,int T){
  29. return sum(R,T)-sum(L -1,T)-sum(R,B -1)+sum(L -1,B -1);
  30. }
  31. };


④单点增减(add) + 立方体求和(query)
⑤立方体增减(update) + 单点求值(sum)

  
  
  1. int arr[MAXN][MAXN][MAXN];
  2. inline int sum(int x,int y,int z){
  3. int res= 0;
  4. for( int i=x;i;i-=lowbit(i))
  5. for( int j=y;j;j-=lowbit(j))
  6. for( int k=z;k;k-=lowbit(k))
  7. res^=arr[i][j][k];
  8. return res;
  9. }
  10. inline void add(int x,int y,int z,int n){
  11. for( int i=x;i<MAXN;i+=lowbit(i))
  12. for( int j=y;j<MAXN;j+=lowbit(j))
  13. for( int k=z;k<MAXN;k+=lowbit(k))
  14. arr[i][j][k]+=n;
  15. }
  16. inline void update(int x1,int y1,int z1,int x2,int y2,int z2,int n){
  17. add(x1,y1,z1,n);
  18. add(x2+ 1,y1,z1,-n);add(x1,y2+ 1,z1,-n);add(x1,y1,z2+ 1,-n);
  19. add(x2+ 1,y2+ 1,z1,n);add(x2+ 1,y1,z2+ 1,n);add(x1,y2+ 1,z2+ 1,n);
  20. add(x2+ 1,y2+ 1,z2+ 1,-n);
  21. }
  22. inline int query(int x1,int y1,int z1,int x2,int y2,int z2){
  23. return sum(x2,y2,z2)
  24. -sum(x2,y2,z1 -1)-sum(x2,y1 -1,z2)-sum(x1 -1,y2,z2)
  25. +sum(x2,y1 -1,z1 -1)+sum(x1 -1,y2,z1 -1)+sum(x1 -1,y1 -1,z2)
  26. -sum(x1 -1,y1 -1,z1 -1);
  27. }


⑥立方体增减(update) + 立方体求和(query)///随便写写……复杂度较高

  
  
  1. template< typename X>
  2. class tree_array_Cube{
  3. struct tree_array_single{
  4. X arr[MAXN][MAXN][MAXN];
  5. X sum(int x,int y,int z){
  6. X res= 0;
  7. for( int i=x;i;i-=lowbit(i))
  8. for( int j=y;j;j-=lowbit(j))
  9. for( int k=z;k;k-=lowbit(k))
  10. res+=arr[i][j][k];
  11. return res;
  12. }
  13. void add(int x,int y,int z,X n){
  14. for( int i=x;i<MAXN;i+=lowbit(i))
  15. for( int j=y;j<MAXN;j+=lowbit(j))
  16. for( int k=z;k<MAXN;k+=lowbit(k))
  17. arr[i][j][k]+=n;
  18. }
  19. }T1,T2,T3,T4,T5,T6,T7,T8;
  20. void add(int x,int y,int z,X n){
  21. T1.add(x,y,z,n);
  22. T2.add(x,y,z,x*n);T3.add(x,y,z,y*n);T4.add(x,y,z,z*n);
  23. T5.add(x,y,z,x*y*n);T6.add(x,y,z,y*z*n);T7.add(x,y,z,x*z*n);
  24. T8.add(x,y,z,x*y*z*n);
  25. }
  26. X sum(int x,int y,int z){
  27. return (x+ 1) (y+1)(z+ 1) T1.sum(x,y,z)
  28. -(y+ 1)(z+ 1) T2.sum(x,y,z)-(x+1)(z+ 1) T3.sum(x,y,z)-(x+1)(y+ 1)*T4.sum(x,y,z)
  29. +(z+ 1)*T5.sum(x,y,z)+(x+ 1)*T6.sum(x,y,z)+(y+ 1)*T7.sum(x,y,z)-T8.sum(x,y,z);
  30. }
  31. public:
  32. void init(){
  33. CLR(T1.arr, 0);CLR(T2.arr, 0);CLR(T3.arr, 0);CLR(T4.arr, 0);
  34. CLR(T5.arr, 0);CLR(T6.arr, 0);CLR(T7.arr, 0);CLR(T8.arr, 0);
  35. }
  36. void update(int x1,int y1,int z1,int x2,int y2,int z2,X n){
  37. add(x1,y1,z1,n);
  38. add(x2+ 1,y1,z1,-n);add(x1,y2+ 1,z1,-n); add(x1,y1,z2+ 1,-n);
  39. add(x2+ 1,y2+ 1,z1,n);add(x2+ 1,y1,z2+ 1,n);add(x1,y2+ 1,z2+ 1,n);
  40. add(x2+ 1,y2+ 1,z2+ 1,-n);
  41. }
  42. X query(int x1,int y1,int z1,int x2,int y2,int z2){
  43. return sum(x2,y2,z2)
  44. -sum(x2,y2,z1 -1)-sum(x2,y1 -1,z2)-sum(x1 -1,y2,z2)
  45. +sum(x2,y1 -1,z1 -1)+sum(x1 -1,y2,z1 -1)+sum(x1 -1,y1 -1,z2)
  46. -sum(x1 -1,y1 -1,z1 -1);
  47. }
  48. };


16、树状数组—区间最大值

  
  
  1. inline void init()
  2. {
  3. CLR(arr, 0);
  4. for( int i= 1;i<=N;++i)
  5. for( int j=i;j<=N&&arr[j]<num[i];j+=lowbit(j))
  6. arr[j]=num[i];
  7. }
  8. inline int query(int L,int R)
  9. {
  10. int res= 0;
  11. for(--L;L<R;){
  12. if(R-lowbit(R)>=L){res=max(res,arr[R]);R-=lowbit(R);}
  13. else{res=max(res,num[R]);--R;}
  14. }
  15. return res;
  16. }
  17. inline void update(int x,int val)
  18. {
  19. int ori=num[x];
  20. num[x]=val;
  21. if(val>=ori)
  22. for( int i=x;i<=N&&arr[i]<val;i+=lowbit(i))
  23. arr[i]=val;
  24. else{
  25. for( int i=x;i<=N&&arr[i]==ori;i+=lowbit(i))
  26. {
  27. arr[i]=val;
  28. for( int j=lowbit(i)>> 1;j;j>>= 1)
  29. arr[i]=max(arr[i],arr[i-j]);
  30. }
  31. }
  32. }




猜你喜欢

转载自blog.csdn.net/qq_36225321/article/details/81838228