线段树模板

来源:互联网 发布:淘宝宝贝命名规则 编辑:程序博客网 时间:2024/05/05 01:40

codevs 1082 线段树练习3

#include<iostream>#include<cstdio>using namespace std;const int maxn=200010*2;long long n;struct cc{    long long l,r,add,sum;}tree[maxn*2];long long yy[maxn];void update(long long p){    tree[p].sum=tree[p*2].sum+tree[p*2+1].sum;    return;}void spread(long long p){    if(!tree[p].add) return;    tree[p*2].add+=tree[p].add;    tree[p*2+1].add+=tree[p].add;    tree[p*2].sum+=tree[p].add*(tree[p*2].r-tree[p*2].l+1);    tree[p*2+1].sum+=tree[p].add*(tree[p*2+1].r-tree[p*2+1].l+1);    tree[p].add=0;    update(p);    return;}void build(long long l,long long r,long long p){    tree[p].l=l,tree[p].r=r;    if(l==r)    {        tree[p].sum=yy[l];        return;    }    long long mid=(tree[p].l+tree[p].r)/2;    build(l,mid,p*2);    build(mid+1,r,p*2+1);    update(p);    return;}void change(long long l,long long r,long long p,long long v){    if(l<=tree[p].l&&tree[p].r<=r)    {        tree[p].add+=v;        tree[p].sum+=v*(tree[p].r-tree[p].l+1);        return;    }    spread(p);    long long mid=(tree[p].l+tree[p].r)/2;    if(l<=mid) change(l,r,p*2,v);    if(mid+1<=r) change(l,r,p*2+1,v);    update(p);    return;}long long ask(long long l,long long r,long long p){    long long ans=0;    if(l<=tree[p].l&&tree[p].r<=r)    {        return tree[p].sum;    }    spread(p);    long long mid=(tree[p].l+tree[p].r)/2;    if(l<=mid) ans+=ask(l,r,p*2);    if(mid+1<=r) ans+=ask(l,r,p*2+1);    update(p);    return ans;}int main(){    scanf("%lld",&n);    for(long long i=1;i<=n;i++)    {        scanf("%lld",&yy[i]);    }    build(1,n,1);    long long q;    scanf("%lld",&q);    for(long long i=1;i<=q;i++)    {        long long x;        scanf("%lld",&x);        if(x==1)        {            long long y,z,v;            scanf("%lld%lld%lld",&y,&z,&v);            change(y,z,1,v);        }        if(x==2)        {            long long y,z;            scanf("%lld%lld",&y,&z);            printf("%lld\n",ask(y,z,1));        }    }    return 0;}
2 0
原创粉丝点击