线段树

来源:互联网 发布:西安行知中学中考喜报 编辑:程序博客网 时间:2024/06/03 17:16
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;int a[55555];int f[205555],laz[205555];int n;int t;void _build(int l,int r,int now)//建树{    if(l==r)    {        f[now]=a[l];        return;    }    int mid=(l+r)>>1;//>>1  右移一位 相当于除以2 速度比除以二稍快    _build(l,mid,now<<1);//<< 1左移一位 相当于乘以2    _build(mid+1,r,now<<1|1);    f[now]=f[now<<1]+f[now<<1|1];//<<1|1  一个数乘以2之后二进制最后一位必定是0 0|1=1  相当于乘以二再加一 }//更新子节点区间值 void pushdown(int l,int r,int now){    int mid=(l+r)>>1;    f[now<<1]+=(mid-l+1)*laz[now];    laz[now<<1]+=laz[now];    f[now<<1|1]+=(r-mid)*laz[now];    laz[now<<1|1]+=laz[now];    laz[now]=0;    return;}int _que(int l,int r,int ll,int rr,int now)//询问区间{    if(ll==l&&rr==r)    {        return f[now];    }    if(laz[now]!=0) pushdown(l,r,now);    int mid=(l+r)>>1;    if(ll>mid)return _que(mid+1,r,ll,rr,now<<1|1);    else if(rr<=mid)return _que(l,mid,ll,rr,now<<1);    else return _que(l,mid,ll,mid,now<<1)+_que(mid+1,r,mid+1,rr,now<<1|1);}void _add(int l,int r,int a,int x,int now)//单节点更新{    if(l==a&&r==a)    {        f[now]+=x;        return;    }    int mid=(l+r)>>1;    if(a<=mid) _add(l,mid,a,x,now<<1);    else _add(mid+1,r,a,x,now<<1|1);    f[now]=f[now<<1]+f[now<<1|1];}void _sub(int l,int r,int a,int x,int now)//单节点更新{    if(l==a&&r==a)    {        f[now]-=x;        return;    }    int mid=(l+r)>>1;    if(a<=mid) _sub(l,mid,a,x,now<<1);    else _sub(mid+1,r,a,x,now<<1|1);    f[now]=f[now<<1]+f[now<<1|1];}//区间更新void update(int l,int r,int ll,int rr,int now,int c){    if(l==ll&&r==rr)    {        f[now]+=c*(r-l+1);        laz[now]+=c;        return;     }       if(laz[now]!=0) pushdown(l,r,now);    int mid=(l+r)>>1;    if(rr<=mid) update(l,mid,ll,rr,now<<1,c);    else if(ll>mid) update(mid+1,r,ll,rr,now<<1|1,c);    else {        update(l,mid,ll,mid,now<<1,c);        update(mid+1,r,mid+1,rr,now<<1|1,c);    }    f[now]=f[now<<1]+f[now<<1|1];}int main(){    scanf("%d",&t);    int k=0;    while(t--)    {        k++;        memset(laz,0,sizeof(laz));        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        _build(1,n,1);        char s[10];        printf("Case %d:\n",k);        while(~scanf("%s",s))        {            if(s[0]=='E')                break;            else if(s[0]=='Q')            {                int a,b;                scanf("%d%d",&a,&b);                int ans=_que(1,n,a,b,1);                printf("%d\n",ans);            }            else if(s[0]=='A')            {                int a,b;                scanf("%d%d",&a,&b);                _add(1,n,a,b,1);            }            else if(s[0]=='S')            {                int a,b;                scanf("%d%d",&a,&b);                _sub(1,n,a,b,1);            }            else if(s[0]=='U')            {                int a,b,c;                scanf("%d%d%d",&a,&b,&c);                update(1,n,a,b,1,c);            }        }    }    return 0;}
原创粉丝点击