[hdu 4348] To the moon

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DT_Kang/article/details/81086688

主席树区间修改模板,用了标记永久化。

#include<cstdio>
#include<iostream>
#define ll long long
using namespace std;
int root[3000010],rs[3000010],ls[3000010],add[3000010];
ll sum[3000010];
int a[3000010],tot;
inline int read()
{
    int x=0,flag=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
    return x*flag;
}
inline void copy(int x,int y)
{
    ls[y]=ls[x],rs[y]=rs[x];
    sum[y]=sum[x],add[y]=add[x];
}
inline void push_up(int x)
{
    sum[x]=sum[ls[x]]+sum[rs[x]];
}
void build(int &root,int l,int r)
{
    root=++tot;
    sum[root]=ls[root]=rs[root]=add[root]=0;
    if(l==r) 
    {
        sum[root]=a[l];
        return;
    }
    int mid=l+r>>1;
    build(ls[root],l,mid);
    build(rs[root],mid+1,r);
    push_up(root);
}
void update(int &root,int pre,int l,int r,int x,int y,int k)
{
    root=++tot;
    copy(pre,root);
    sum[root]+=1ll*(y-x+1)*k;
    if(x==l&&y==r)
    {
        add[root]+=k;
        return;
    }
    int mid=l+r>>1;
    if(y<=mid) update(ls[root],ls[pre],l,mid,x,y,k);
    else if(x>mid) update(rs[root],rs[pre],mid+1,r,x,y,k);
    else 
    {
        update(ls[root],ls[pre],l,mid,x,mid,k);
        update(rs[root],rs[pre],mid+1,r,mid+1,y,k);
    }
}
ll query(int root,int l,int r,int x,int y)
{
    if(x==l&&y==r) return sum[root];
    ll ans=1ll*add[root]*(y-x+1);
    int mid=l+r>>1;
    if(y<=mid) ans+=query(ls[root],l,mid,x,y);
    else if(x>mid) ans+=query(rs[root],mid+1,r,x,y);
    else 
    {
        ans+=query(ls[root],l,mid,x,mid);
        ans+=query(rs[root],mid+1,r,mid+1,y);
    }
    return ans;
}
int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        tot=0;
        int now=0,l,r,k;
        for(int i=1;i<=n;i++) a[i]=read();
        build(root[0],1,n);
        while(m--)
        {
            char s[5];
            scanf("%s",s);
            if(s[0]=='Q') l=read(),r=read(),cout<<query(root[now],1,n,l,r)<<'\n';
            else if(s[0]=='C') l=read(),r=read(),k=read(),update(root[now+1],root[now],1,n,l,r,k),now++;
            else if(s[0]=='H') l=read(),r=read(),k=read(),cout<<query(root[k],1,n,l,r)<<'\n';
            else now=read();
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/DT_Kang/article/details/81086688
今日推荐