主席树。区间更新区间查询。调的要死。因为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 ",query(u,v,1,n,cur)); }else if(s[0]=='H'){ u=read(),v=read(),d=read(); printf("%lld ",query(u,v,1,n,root[d])); }else{ cnt=u=read();cur=root[cnt]; } } } return 0; }