主席树。区间更新区间查询。调的要死。因为update 忘了op->col=t->col。然后一直WA。。。而且开始自己的写法是错的。。。后来就换了一种写法。。。QAQ
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define ll long long
ll readll(){
ll x=0;char c=getchar();bool f=true;
while(!isdigit(c)) {
if(c=='-') f=false;c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return f?x:-x;
}
int read(){
int x=0;char c=getchar();bool f=true;
while(!isdigit(c)) {
if(c=='-') f=false;c=getchar();
}
while(isdigit(c)) x=x*10+c-'0',c=getchar();
return f?x:-x;
}
const int nmax=100005;
const int inf=0x7f7f7f7f;
struct node{
node *l,*r;ll sum,col;
};
node nodes[nmax*24],*root[nmax],*pt;
node* build(int l,int r){
node* op=pt++;op->col=0;
if(l==r){
op->sum=readll();return op;
}
int mid=(l+r)>>1;
op->l=build(l,mid);op->r=build(mid+1,r);
op->sum=op->l->sum+op->r->sum;
return op;
}
node* update(int tl,int tr,ll add,int l,int r,node* t){
node* op=pt++;op->sum=t->sum+add*(tr-tl+1); op->l=t->l,op->r=t->r;op->col=t->col;//if not here is wrong
if(tl==l&&tr==r) {
op->col+=add;return op;
}
int mid=(l+r)>>1;
if(tr<=mid) op->l=update(tl,tr,add,l,mid,t->l);
else if(tl>mid) op->r=update(tl,tr,add,mid+1,r,t->r);
else op->l=update(tl,mid,add,l,mid,t->l),op->r=update(mid+1,tr,add,mid+1,r,t->r);
/*if(tl<=mid) op->l=update(tl,mid,add,l,mid,t->l);
if(tr>mid) op->r=update(mid+1,tr,add,mid+1,r,t->r);*/
return op;
}
ll query(int tl,int tr,int l,int r,node* t){
if(tl==l&&tr==r) return t->sum;
int mid=(l+r)>>1;ll ans=t->col*(tr-tl+1);
if(tr<=mid) return ans+=query(tl,tr,l,mid,t->l);
if(tl>mid) return ans+=query(tl,tr,mid+1,r,t->r);
return ans+=query(tl,mid,l,mid,t->l)+query(mid+1,tr,mid+1,r,t->r);
/*if(tl<=mid) ans+=query(tl,mid,l,mid,t->l);
if(tr>mid) ans+=query(mid+1,tr,mid+1,r,t->r);if(tl==4,tr==4)wrong answer...*/
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
pt=nodes;
root[0]=build(1,n);
node* cur=root[0];
int u,v,cnt=0;ll d;char s[5];
rep(i,1,m){
scanf("%s",s);
if(s[0]=='C'){
u=read(),v=read(),d=readll();
root[++cnt]=update(u,v,d,1,n,cur);
cur=root[cnt];
}else if(s[0]=='Q'){
u=read(),v=read();
printf("%lld\n",query(u,v,1,n,cur));
}else if(s[0]=='H'){
u=read(),v=read(),d=read();
printf("%lld\n",query(u,v,1,n,root[d]));
}else{
cnt=u=read();cur=root[cnt];
}
}
}
return 0;
}