线段树维护区间和

新学习了线段树,打了线段树维护区间和的模板。

#include<cstdio>

#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)

#define MAXNUM 100001
#define INF ((1<<31)-1)
#define left(a) (a<<1)
#define right(a) ((a<<1)+1)

int n,q;
long long arr[MAXNUM];

struct SegTreeNode{
    long long val;
    long long lazy;
    SegTreeNode(){
        val=0;
        lazy=0;
    }
}node[MAXNUM*5];

void tree_update(int root){
    long long a=node[left(root)].val,b=node[right(root)].val;
    node[root].val=a+b;
    return;
}
void lazy_push(int root,int l,int r){
    node[left(root)].lazy+=node[root].lazy;
    node[right(root)].lazy+=node[root].lazy;
    node[root].val+=(r-l+1)*node[root].lazy;
    node[root].lazy=0;
}
void tree_build(int root,long long arr[],int bl,int br){
    node[root].lazy=0;
    if(bl==br) node[root].val=arr[bl];
    else{
        int mid=(bl+br)/2;
        tree_build(left(root),arr,bl,mid);
        tree_build(right(root),arr,mid+1,br);
        tree_update(root);
    }
    return;
}
void tree_add(int root,int al,int ar,int l,int r,long long k){
    if(r<al||ar<l) return;
    if(l==al&&r==ar){
        node[root].lazy+=k;
        return;
    }
    lazy_push(root,l,r);
    int mid=(l+r)/2;
    if(mid>=al) tree_add(left(root),al,min(mid,ar),l,mid,k);
    if(mid<ar) tree_add(right(root),max(mid+1,al),ar,mid+1,r,k);
    lazy_push(left(root),l,mid);
    lazy_push(right(root),mid+1,r);
    tree_update(root);
    return;
}
long long ques(int root,int ql,int qr,int l,int r){
    if(l>r) return 0;
    if(l==ql&&r==qr) return node[root].lazy*(r-l+1)+node[root].val;
    lazy_push(root,l,r);
    int mid=(l+r)/2;
    long long ans=0;
    if(mid>=ql) ans+=ques(left(root),ql,min(mid,qr),l,mid);
    if(mid<qr) ans+=ques(right(root),max(mid+1,ql),qr,mid+1,r);
    return ans;
}

int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) scanf("%lld",&arr[i]);
    tree_build(1,arr,1,n);
    while(q--){
        int p,x,y;
        long long k;
        scanf("%d",&p);
        if(p==1){
            scanf("%d%d%lld",&x,&y,&k);
            tree_add(1,x,y,1,n,k);
        }
        if(p==2){
            scanf("%d%d",&x,&y);
            printf("%lld\n",ques(1,x,y,1,n));
        }
    }
    return 0;
}
代码

就是这样了。

posted @ 2017-11-14 20:59  Halifuda  阅读(224)  评论(0编辑  收藏  举报