http://acm.hdu.edu.cn/showproblem.php?pid=4348

#include"iostream"
#include"cstdio"
using namespace std;
const int maxn=1e5+5;
int Scan()
{
    int res = 0, flag = 0;
    char ch;
    if((ch = getchar()) == '-') flag = 1;
    else if(ch >= '0' && ch <= '9') res = ch - '0';
    while((ch = getchar()) >= '0' && ch <= '9')
        res = res * 10 + (ch - '0');
    return flag ? -res : res;
}
int N,M;
struct Tree
{
    int Ls,Rs,L,R,lazy;
    long long sum;
};
Tree tree[maxn<<4];
int root[maxn];
int tot,rt;
int Build(int L,int R)
{
    int id=++tot;
    tree[id].lazy=0;
    tree[id].L=L;
    tree[id].R=R;
    if(L==R)
    {
        tree[id].sum=Scan();
        return id;
    }
    int mid=(L+R)>>1;
    tree[id].Ls=Build(L,mid);
    tree[id].Rs=Build(mid+1,R);
    tree[id].sum=tree[tree[id].Ls].sum+tree[tree[id].Rs].sum;
    return id;
}
void Update(int id)
{
    int ls=tree[id].Ls;
    int rs=tree[id].Rs;

    tree[id].sum=tree[ls].sum+tree[rs].sum;
    if(tree[ls].lazy)tree[id].sum+=tree[ls].lazy*(tree[ls].R-tree[ls].L+1);
    if(tree[rs].lazy)tree[id].sum+=tree[rs].lazy*(tree[rs].R-tree[rs].L+1);
}
int Add(int id1,int L,int R,int v)
{
    int id2=++tot;
    tree[id2].L=tree[id1].L;
    tree[id2].R=tree[id1].R;
    tree[id2].lazy=tree[id1].lazy;

    if(L<=tree[id1].L&&R>=tree[id1].R)
    {
        tree[id2].Ls=tree[id1].Ls;
        tree[id2].Rs=tree[id1].Rs;
        tree[id2].sum=tree[id1].sum;
        tree[id2].lazy=tree[id1].lazy+v;
        return id2;
    }
    int mid=(tree[id1].L+tree[id1].R)>>1;
    if(R<=mid)
    {
        tree[id2].Ls=Add(tree[id1].Ls,L,R,v);
        tree[id2].Rs=tree[id1].Rs;
    }
    else if(L>mid)
    {
        tree[id2].Rs=Add(tree[id1].Rs,L,R,v);
        tree[id2].Ls=tree[id1].Ls;
    }
    else
    {
        tree[id2].Ls=Add(tree[id1].Ls,L,mid,v);
        tree[id2].Rs=Add(tree[id1].Rs,mid+1,R,v);
    }
    Update(id2);
    return id2;
}
long long Query(int id,int L,int R,int add)
{
    if(L<=tree[id].L&&R>=tree[id].R)return tree[id].sum+(R-L+1)*(add+tree[id].lazy);
    int mid=(tree[id].L+tree[id].R)>>1;
    if(R<=mid)return Query(tree[id].Ls,L,R,add+tree[id].lazy);
    else if(L>mid)return Query(tree[id].Rs,L,R,add+tree[id].lazy);
    else
    {
        return Query(tree[id].Ls,L,mid,add+tree[id].lazy)+Query(tree[id].Rs,mid+1,R,add+tree[id].lazy);
    }
}
int main()
{
// freopen("2.txt","r",stdin); 
    char cmd;
    int L,R,v,T;
    while(cin>>N>>M)
    {
        tot=0;
        Build(1,N);
        root[0]=1;
        rt=0;
        while(M--)
        {
            cin>>cmd;
            if(cmd=='Q')
            {
                int L,R;
                L=Scan();
                R=Scan();
                cout<<Query(root[rt],L,R,0)<<"\n";
            }
            else if(cmd=='C')
            {
                L=Scan();
                R=Scan();
                v=Scan();
                rt++;
                root[rt]=Add(root[rt-1],L,R,v);
            }
            else if(cmd=='H')
            {
                L=Scan();
                R=Scan();
                T=Scan();
                cout<<Query(root[T],L,R,0)<<"\n";
            }
            else if(cmd=='B')
            {
                rt=Scan();
                tot=root[rt+1]-1;//不要这句就TLE,估计是超内存了 
            }
        }
    }
}