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,估计是超内存了
}
}
}
}