线段树求和

来源:互联网 发布:阿里云汽车荣威rx5 编辑:程序博客网 时间:2024/05/22 11:46

依旧是单纯地存个板。
指针实现。
区间修改区间查询

#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const int N = 400010;int n,m;int a[N];struct node{    ll sum,flag;    node *ls,*rs;    void update(){        sum=ls->sum+rs->sum;    }    void pushdown(int l,int r){        if(flag){            int mid=(l+r)>>1;            ls->sum+=(long long)(mid-l+1)*flag;            ls->flag+=flag;            rs->sum+=(long long)(r-mid)*flag;            rs->flag+=flag;            flag=0;        }    }}pool[N],*tail=pool,*root;node *build(int l,int r){    node *bt=++tail;    if(l==r){        bt->sum=a[l];        bt->flag=0;    }    else{        int mid=(l+r)>>1;        bt->ls=build(l,mid);        bt->rs=build(mid+1,r);        bt->update();        bt->flag=0;    }    return bt;}void modify(node *bt,int l,int r,int pos,int val,int delta){    if(pos<=l&&val>=r){        bt->sum+=(long long)(r-l+1)*delta;        bt->flag+=delta;        return ;    }    int mid=(l+r)>>1;    bt->pushdown(l,r);    if(pos<=mid) modify(bt->ls,l,mid,pos,val,delta);    if(val>mid) modify(bt->rs,mid+1,r,pos,val,delta);    bt->update();} ll query(node *bt,int l,int r,int pos,int val){    if(pos<=l&&val>=r)        return bt->sum;    int mid=l+r>>1;    bt->pushdown(l,r);    ll ans=0;    if(pos<=mid) ans+=query(bt->ls,l,mid,pos,val);    if(val>mid) ans+=query(bt->rs,mid+1,r,pos,val);    return ans;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    root=build(1,n);    scanf("%d",&m);    for(int i=1;i<=m;i++){        int d;        scanf("%d",&d);        if(d==1){            int l,r,delta;            scanf("%d%d%d",&l,&r,&delta);            modify(root,1,n,l,r,delta);        }        if(d==2){            int l,r;            scanf("%d%d",&l,&r);            printf("%lld\n",query(root,1,n,l,r));        }    }    return 0;}

数组

#include<cstdio>#include<cstring>#define ll long longusing namespace std;const int N = 4000010;int n,m;int a[N];struct node{    ll sum,flag;    int l,r;    }tree[N];void pushdown(int root){    int flag=tree[root].flag;    int l=tree[root].l,r=tree[root].r;    if(flag){        int mid=(l+r)>>1;        tree[root<<1].flag+=flag;        tree[root<<1|1].flag+=flag;        tree[root<<1|1].sum+=(long long)(r-mid)*flag;        tree[root<<1].sum+=(long long)(mid-l+1)*flag;        tree[root].flag=0;    }}void build(int root,int l,int r){    tree[root].l=l,tree[root].r=r;    if(l==r){        tree[root].sum=a[l];        tree[root].flag=0;    }    else{        int mid=(l+r)>>1;        build(root<<1,l,mid);        build(root<<1|1,mid+1,r);        tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;        tree[root].flag=0;    }}void modify(int root,int pos,int val,int delta){    int l=tree[root].l,r=tree[root].r;    if(l>=pos&&r<=val){        tree[root].sum+=(long long)(r-l+1)*delta;        tree[root].flag+=delta;        return ;    }    int mid=(l+r)>>1;    pushdown(root);    if(pos<=mid) modify(root<<1,pos,val,delta);    if(val>mid) modify(root<<1|1,pos,val,delta);    tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;}ll query(int root,int pos,int val){    int l=tree[root].l,r=tree[root].r;    if(l>=pos&&r<=val)        return tree[root].sum;    ll ans=0;    pushdown(root);    int mid=(l+r)>>1;    if(pos<=mid) ans+=query(root<<1,pos,val);    if(val>mid) ans+=query(root<<1|1,pos,val);    return ans;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        scanf("%d",&a[i]);    build(1,1,n);    scanf("%d",&m);    for(int i=1;i<=m;i++){        int d;        scanf("%d",&d);        if(d==1){            int l,r,delta;            scanf("%d%d%d",&l,&r,&delta);            modify(1,l,r,delta);        }        if(d==2){            int l,r;            scanf("%d%d",&l,&r);            printf("%lld\n",query(1,l,r));        }    }    return 0;}
原创粉丝点击