主席树区间更新模板
对于主席树中的每一颗线段树 除了左右区间的位置与父区间不再有任何关系以外 其他都是一模一样
但是因为主席树中的线段树每一个区间和左右子区间的关系不好找 只能pushup 不能pushdown
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define ll long long struct node { int nl; int nr; ll val; ll laz; }; node tree[2500010]; int root[100010]; int n,num,now; int build(int l,int r) { int m,cur; cur=num++; tree[cur].nl=0,tree[cur].nr=0; tree[cur].val=0,tree[cur].laz=0; if(l==r) { scanf("%lld",&tree[cur].val); return cur; } m=(l+r)/2; tree[cur].nl=build(l,m); tree[cur].nr=build(m+1,r); tree[cur].val=tree[tree[cur].nl].val+tree[tree[cur].nr].val; return cur; } int update(int rot,int pl,int pr,ll val,int l,int r) { int m,cur; cur=num++; tree[cur]=tree[rot]; tree[cur].val+=val*(min(pr,r)-max(pl,l)+1); if(pl<=l&&r<=pr) { tree[cur].laz+=val; return cur; } m=(l+r)/2; if(pl<=m) tree[cur].nl=update(tree[cur].nl,pl,pr,val,l,m); if(pr>m) tree[cur].nr=update(tree[cur].nr,pl,pr,val,m+1,r); return cur; } ll query(int cur,int pl,int pr,int l,int r) { ll res; int m; if(pl<=l&&r<=pr) { return tree[cur].val; } res=tree[cur].laz*(min(pr,r)-max(pl,l)+1); m=(l+r)/2; if(pl<=m) res+=query(tree[cur].nl,pl,pr,l,m); if(pr>m) res+=query(tree[cur].nr,pl,pr,m+1,r); return res; } int main() { ll val; int q,flag,l,r,t; char ch[10]; flag=0; while(scanf("%d%d",&n,&q)!=EOF) { if(flag) printf("\n"); else flag=1; memset(tree,0,sizeof(tree)); memset(root,0,sizeof(root)); num=0,now=0; root[now]=build(1,n); while(q--) { scanf("%s",ch); if(ch[0]=='C') { scanf("%d%d%lld",&l,&r,&val); now++; root[now]=update(root[now-1],l,r,val,1,n); } else if(ch[0]=='Q') { scanf("%d%d",&l,&r); printf("%lld\n",query(root[now],l,r,1,n)); } else if(ch[0]=='H') { scanf("%d%d%d",&l,&r,&t); printf("%lld\n",query(root[t],l,r,1,n)); } else { scanf("%d",&now); } } } return 0; }