树状数组

xiaoxiao2021-02-28  101

转载 来自http://blog.csdn.net/lawrence_jang/article/details/8054173 14、树状数组 (1)、单点增减+区间求和 思路:C[x]表示该点的元素:sum(x)=C[1]+C[2]+……C[x] [cpp] view plain copy print ? int arr[MAXN];  inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbit(x);return res;}  inline void add(int x,int n){while(x<MAXN)arr[x]+=n,x+=lowbit(x);}  inline int query(int x,int y){return sum(y)-sum(x-1);}   int arr[MAXN]; inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbit(x);return res;} inline void add(int x,int n){while(x<MAXN)arr[x]+=n,x+=lowbit(x);} inline int query(int x,int y){return sum(y)-sum(x-1);} (2)、区间增减+单点查询 思路:C[x]表示该点元素与左边元素的差值:num[x]=C[1]+C[2]+……C[x] [cpp] view plain copy print ? int arr[MAXN]  inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbit(x);return res;}  inline void add(int x,int n){while(x<MAXN)arr[x]+=n,x+=lowbit(x);}  inline int update(int x,int y,int n){add(x,n);add(y+1,-n);}   int arr[MAXN] inline int sum(int x){int res=0;while(x)res+=arr[x],x-=lowbit(x);return res;} inline void add(int x,int n){while(x<MAXN)arr[x]+=n,x+=lowbit(x);} inline int update(int x,int y,int n){add(x,n);add(y+1,-n);} (3)、区间增减+区间查询 思路:C1[x]表示该点元素与左边的差值,C2[x]表示的是x*C[x] [cpp] view plain copy print ? 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);   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); 则可以想到用C1[x]维护C[x]的值,C2[x]维护x*C[X]的值 [cpp] view plain copy print ? template <typename X>  struct tree_array{      struct tree_array_single{          X arr[MAXN];          void add(int x,X n){while(x<=N)arr[x]+=n,x+=lowbit(x);}          X sum(int x){X sum=0;while(x)sum+=arr[x],x-=lowbit(x);return sum;}      }T1,T2;      void reset(){CLR(T1.arr,0); CLR(T2.arr,0);}      void add(int x,X n){T1.add(x,n);T2.add(x,x*n);}      void update(int L,int R,int n){add(L,n);add(R+1,-n);}      X sum(int x){return (x+1)*T1.sum(x)-T2.sum(x);}      X query(int L,int R){return sum(R)-sum(L-1);}  };   template <typename X> struct tree_array{ struct tree_array_single{ X arr[MAXN]; void add(int x,X n){while(x<=N)arr[x]+=n,x+=lowbit(x);} X sum(int x){X sum=0;while(x)sum+=arr[x],x-=lowbit(x);return sum;} }T1,T2; void reset(){CLR(T1.arr,0); CLR(T2.arr,0);} void add(int x,X n){T1.add(x,n);T2.add(x,x*n);} void update(int L,int R,int n){add(L,n);add(R+1,-n);} X sum(int x){return (x+1)*T1.sum(x)-T2.sum(x);} X query(int L,int R){return sum(R)-sum(L-1);} }; 15、多维树状数组 ①单点增减(add) + 矩形求和(query)  ②矩形增减(update) + 单点求值(sum) [cpp] view plain copy print ? int arr[MAXN][MAXN]  inline void add(int x,int y,int n) {      for(int i=x;i<MAXN;i+=lowbit(i))          for(int j=y;j<MAXN;j+=lowbit(j))              arr[i][j]+=n;  }  inline int sum(int x,int y){      int res=0;      for(int i=x;i;i-=lowbit(i))          for(int j=y;j;j-=lowbit(j))              res+=arr[i][j];      return res;  }  inline int query(int L,int B,int R,int T) {      return sum(R,T)+sum(L-1,B-1)-sum(R,B-1)-sum(L-1,T);  }  inline void update(int L,int B,int R,int T,int n){      update(L,B,n);update(L,T+1,n);update(R+1,B,n);update(R+1,T+1,n);  }   int arr[MAXN][MAXN] inline void add(int x,int y,int n) { for(int i=x;i<MAXN;i+=lowbit(i)) for(int j=y;j<MAXN;j+=lowbit(j)) arr[i][j]+=n; } inline int sum(int x,int y){ int res=0; for(int i=x;i;i-=lowbit(i)) for(int j=y;j;j-=lowbit(j)) res+=arr[i][j]; return res; } inline int query(int L,int B,int R,int T) { return sum(R,T)+sum(L-1,B-1)-sum(R,B-1)-sum(L-1,T); } inline void update(int L,int B,int R,int T,int n){ update(L,B,n);update(L,T+1,n);update(R+1,B,n);update(R+1,T+1,n); } ③矩形增减(update)+ 矩形求和(query) [cpp] view plain copy print ? template<typename X>  class tree_array{      struct tree_array_single{          X arr[MAXN][MAXN];          void add(int x,int y,X n){              for(int i=x; i<MAXN; i+=lowbit(i))                  for(int j=y; j<MAXN; j+=lowbit(j))                      arr[i][j]+=n;          }          X sum(int x,int y){              X res=0;              for(int i=x; i; i-=lowbit(i))                  for(int j=y; j; j-=lowbit(j))                      res+=arr[i][j];              return res;          }      } T1,T2,T3,T4;      void add(int x,int y,int n){          T1.add(x,y,n);T2.add(x,y,y*n);T3.add(x,y,x*n);T4.add(x,y,x*y*n);      }      X sum(int x,int y){      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);}  public:      void init(){CLR(T1.arr,0);CLR(T2.arr,0);CLR(T3.arr,0);CLR(T4.arr,0);}      void update(int L,int B,int R,int T,int n){          add(L,B,n);add(L,T+1,-n);add(R+1,B,-n);add(R+1,T+1,n);      }      X query(int L,int B,int R,int T){          return sum(R,T)-sum(L-1,T)-sum(R,B-1)+sum(L-1,B-1);      }  };   template<typename X> class tree_array{ struct tree_array_single{ X arr[MAXN][MAXN]; void add(int x,int y,X n){ for(int i=x; i<MAXN; i+=lowbit(i)) for(int j=y; j<MAXN; j+=lowbit(j)) arr[i][j]+=n; } X sum(int x,int y){ X res=0; for(int i=x; i; i-=lowbit(i)) for(int j=y; j; j-=lowbit(j)) res+=arr[i][j]; return res; } } T1,T2,T3,T4; void add(int x,int y,int n){ T1.add(x,y,n);T2.add(x,y,y*n);T3.add(x,y,x*n);T4.add(x,y,x*y*n); } X sum(int x,int y){ 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);} public: void init(){CLR(T1.arr,0);CLR(T2.arr,0);CLR(T3.arr,0);CLR(T4.arr,0);} void update(int L,int B,int R,int T,int n){ add(L,B,n);add(L,T+1,-n);add(R+1,B,-n);add(R+1,T+1,n); } X query(int L,int B,int R,int T){ return sum(R,T)-sum(L-1,T)-sum(R,B-1)+sum(L-1,B-1); } }; ④单点增减(add) + 立方体求和(query) ⑤立方体增减(update) + 单点求值(sum) [cpp] view plain copy print ? int arr[MAXN][MAXN][MAXN];  inline int sum(int x,int y,int z){      int res=0;      for(int i=x;i;i-=lowbit(i))          for(int j=y;j;j-=lowbit(j))              for(int k=z;k;k-=lowbit(k))                  res^=arr[i][j][k];      return res;  }  inline void add(int x,int y,int z,int n){       for(int i=x;i<MAXN;i+=lowbit(i))          for(int j=y;j<MAXN;j+=lowbit(j))              for(int k=z;k<MAXN;k+=lowbit(k))                  arr[i][j][k]+=n;  }  inline void update(int x1,int y1,int z1,int x2,int y2,int z2,int n){  add(x1,y1,z1,n);  add(x2+1,y1,z1,-n);add(x1,y2+1,z1,-n);add(x1,y1,z2+1,-n);  add(x2+1,y2+1,z1,n);add(x2+1,y1,z2+1,n);add(x1,y2+1,z2+1,n);  add(x2+1,y2+1,z2+1,-n);  }  inline int query(int x1,int y1,int z1,int x2,int y2,int z2){      return sum(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);  }   int arr[MAXN][MAXN][MAXN]; inline int sum(int x,int y,int z){ int res=0; for(int i=x;i;i-=lowbit(i)) for(int j=y;j;j-=lowbit(j)) for(int k=z;k;k-=lowbit(k)) res^=arr[i][j][k]; return res; } inline void add(int x,int y,int z,int n){ for(int i=x;i<MAXN;i+=lowbit(i)) for(int j=y;j<MAXN;j+=lowbit(j)) for(int k=z;k<MAXN;k+=lowbit(k)) arr[i][j][k]+=n; } inline void update(int x1,int y1,int z1,int x2,int y2,int z2,int n){ add(x1,y1,z1,n); add(x2+1,y1,z1,-n);add(x1,y2+1,z1,-n);add(x1,y1,z2+1,-n); add(x2+1,y2+1,z1,n);add(x2+1,y1,z2+1,n);add(x1,y2+1,z2+1,n); add(x2+1,y2+1,z2+1,-n); } inline int query(int x1,int y1,int z1,int x2,int y2,int z2){ return sum(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); } ⑥立方体增减(update) + 立方体求和(query)///随便写写……复杂度较高 [cpp] view plain copy print ? template<typename X>  class tree_array_Cube{      struct tree_array_single{          X arr[MAXN][MAXN][MAXN];          X sum(int x,int y,int z){              X res=0;              for(int i=x;i;i-=lowbit(i))                  for(int j=y;j;j-=lowbit(j))                      for(int k=z;k;k-=lowbit(k))                          res+=arr[i][j][k];              return res;          }          void add(int x,int y,int z,X n){              for(int i=x;i<MAXN;i+=lowbit(i))                  for(int j=y;j<MAXN;j+=lowbit(j))                      for(int k=z;k<MAXN;k+=lowbit(k))                          arr[i][j][k]+=n;          }      }T1,T2,T3,T4,T5,T6,T7,T8;      void add(int x,int y,int z,X n){          T1.add(x,y,z,n);          T2.add(x,y,z,x*n);T3.add(x,y,z,y*n);T4.add(x,y,z,z*n);          T5.add(x,y,z,x*y*n);T6.add(x,y,z,y*z*n);T7.add(x,y,z,x*z*n);          T8.add(x,y,z,x*y*z*n);      }      X sum(int x,int y,int z){          return (x+1)*(y+1)*(z+1)*T1.sum(x,y,z)          -(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)          +(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);      }  public:      void init(){          CLR(T1.arr,0);CLR(T2.arr,0);CLR(T3.arr,0);CLR(T4.arr,0);          CLR(T5.arr,0);CLR(T6.arr,0);CLR(T7.arr,0);CLR(T8.arr,0);      }      void update(int x1,int y1,int z1,int x2,int y2,int z2,X n){          add(x1,y1,z1,n);          add(x2+1,y1,z1,-n);add(x1,y2+1,z1,-n); add(x1,y1,z2+1,-n);          add(x2+1,y2+1,z1,n);add(x2+1,y1,z2+1,n);add(x1,y2+1,z2+1,n);          add(x2+1,y2+1,z2+1,-n);      }      X query(int x1,int y1,int z1,int x2,int y2,int z2){          return sum(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);      }  };   template<typename X> class tree_array_Cube{ struct tree_array_single{ X arr[MAXN][MAXN][MAXN]; X sum(int x,int y,int z){ X res=0; for(int i=x;i;i-=lowbit(i)) for(int j=y;j;j-=lowbit(j)) for(int k=z;k;k-=lowbit(k)) res+=arr[i][j][k]; return res; } void add(int x,int y,int z,X n){ for(int i=x;i<MAXN;i+=lowbit(i)) for(int j=y;j<MAXN;j+=lowbit(j)) for(int k=z;k<MAXN;k+=lowbit(k)) arr[i][j][k]+=n; } }T1,T2,T3,T4,T5,T6,T7,T8; void add(int x,int y,int z,X n){ T1.add(x,y,z,n); T2.add(x,y,z,x*n);T3.add(x,y,z,y*n);T4.add(x,y,z,z*n); T5.add(x,y,z,x*y*n);T6.add(x,y,z,y*z*n);T7.add(x,y,z,x*z*n); T8.add(x,y,z,x*y*z*n); } X sum(int x,int y,int z){ return (x+1)*(y+1)*(z+1)*T1.sum(x,y,z) -(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) +(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); } public: void init(){ CLR(T1.arr,0);CLR(T2.arr,0);CLR(T3.arr,0);CLR(T4.arr,0); CLR(T5.arr,0);CLR(T6.arr,0);CLR(T7.arr,0);CLR(T8.arr,0); } void update(int x1,int y1,int z1,int x2,int y2,int z2,X n){ add(x1,y1,z1,n); add(x2+1,y1,z1,-n);add(x1,y2+1,z1,-n); add(x1,y1,z2+1,-n); add(x2+1,y2+1,z1,n);add(x2+1,y1,z2+1,n);add(x1,y2+1,z2+1,n); add(x2+1,y2+1,z2+1,-n); } X query(int x1,int y1,int z1,int x2,int y2,int z2){ return sum(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); } }; 16、树状数组—区间最大值 [cpp] view plain copy print ? inline void init()  {      CLR(arr,0);      for(int i=1;i<=N;++i)          for(int j=i;j<=N&&arr[j]<num[i];j+=lowbit(j))              arr[j]=num[i];  }  inline int query(int L,int R)  {      int res=0;      for(–L;L<R;){          if(R-lowbit(R)>=L){res=max(res,arr[R]);R-=lowbit(R);}          else{res=max(res,num[R]);–R;}      }      return res;  }  inline void update(int x,int val)  {      int ori=num[x];      num[x]=val;      if(val>=ori)          for(int i=x;i<=N&&arr[i]<val;i+=lowbit(i))              arr[i]=val;      else{          for(int i=x;i<=N&&arr[i]==ori;i+=lowbit(i))          {              arr[i]=val;              for(int j=lowbit(i)>>1;j;j>>=1)                  arr[i]=max(arr[i],arr[i-j]);          }      }  }   inline void init() { CLR(arr,0); for(int i=1;i<=N;++i) for(int j=i;j<=N&&arr[j]<num[i];j+=lowbit(j)) arr[j]=num[i]; } inline int query(int L,int R) { int res=0; for(--L;L<R;){ if(R-lowbit(R)>=L){res=max(res,arr[R]);R-=lowbit(R);} else{res=max(res,num[R]);--R;} } return res; } inline void update(int x,int val) { int ori=num[x]; num[x]=val; if(val>=ori) for(int i=x;i<=N&&arr[i]<val;i+=lowbit(i)) arr[i]=val; else{ for(int i=x;i<=N&&arr[i]==ori;i+=lowbit(i)) { arr[i]=val; for(int j=lowbit(i)>>1;j;j>>=1) arr[i]=max(arr[i],arr[i-j]); } } }
转载请注明原文地址: https://www.6miu.com/read-46243.html

最新回复(0)