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

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

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


(3)、区间增减+区间查询
思路:C1[x]表示该点元素与左边的差值,C2[x]表示的是x*C[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]的值
template 
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)
int arr[MAXN][MAXN]
inline void add(int x,int y,int n) {
    for(int i=x;i


③矩形增减(update)+ 矩形求和(query)
template
class tree_array{
    struct tree_array_single{
        X arr[MAXN][MAXN];
        void add(int x,int y,X n){
            for(int i=x; i


④单点增减(add) + 立方体求和(query)
⑤立方体增减(update) + 单点求值(sum)
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


⑥立方体增减(update) + 立方体求和(query)///随便写写……复杂度较高
template
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


16、树状数组—区间最大值
inline void init()
{
    CLR(arr,0);
    for(int i=1;i<=N;++i)
        for(int j=i;j<=N&&arr[j]=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]>1;j;j>>=1)
                arr[i]=max(arr[i],arr[i-j]);
        }
    }
}


你可能感兴趣的:(数据结构学习,模板_全手打)