SegmentTree_2 ( PushDown )

#include<cstdio>
#define int long long
#define MAXN 100005

int n,m,c[MAXN<<2],add[MAXN<<2],a[MAXN];

inline void pushdown(int k,int l,int r){
    if(!add[k])return;
    int mid=(l+r)>>1;
    add[k<<1]+=add[k];
    c[k<<1]+=add[k]*(mid-l+1);
    add[k<<1|1]+=add[k];
    c[k<<1|1]+=add[k]*(r-mid);
    add[k]=0;
}

inline void build(int k,int l,int r){
    if(l==r){
        c[k]=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    c[k]=c[k<<1]+c[k<<1|1];
}

inline void modify(int k,int l,int r,int xl,int xr,int x){
    if(xl<=l&&r<=xr){
        c[k]+=(r-l+1)*x;
        add[k]+=x;
        return;
    }
    pushdown(k,l,r);
    int mid=(l+r)>>1;
    if(xl<=mid)modify(k<<1,l,mid,xl,xr,x);
    if(xr>=mid+1)modify(k<<1|1,mid+1,r,xl,xr,x);
    c[k]=c[k<<1]+c[k<<1|1];
}

inline int query(int k,int l,int r,int xl,int xr){
    if(xl<=l&&r<=xr){
        return c[k];
    }
    pushdown(k,l,r);
    int mid=(l+r)>>1,qvq=0;
    if(xl<=mid)qvq+=query(k<<1,l,mid,xl,xr);
    if(xr>=mid+1)qvq+=query(k<<1|1,mid+1,r,xl,xr);
    return qvq;
}

signed main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt;
        scanf("%lld",&opt);
        if(opt-1){
            int x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(1,1,n,x,y));
        }
        else {
            int x,y,z;
            scanf("%lld%lld%lld",&x,&y,&z);
            modify(1,1,n,x,y,z);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/Y15BeTa/p/11745489.html