题解:因为该题涉及到线段树要还原回去,那么肯定用主席树的区间修改区间查询,我们更新的时候直接将该点的总和加上一个(r-l)*v;
然后查询的时候上面的lazy传递下来,然后再补上(R-L+1)*x,x = 传递下来的lazy总和
#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define mes(a,b) memset(a,b,sizeof(a)) #define rep(i,a,b) for(int i = a; i <= b; i++) #define dec(i,a,b) for(int i = b; i >= a; i--) #define fi first #define se second #define ls rt<<1 #define rs rt<<1|1 #define lson ls,L,mid #define rson rs,mid+1,R #define lowbit(x) x&(-x) typedef double db; typedef long long int ll; typedef pair pii; typedef unsigned long long ull; const ll inf = 0x3f3f3f3f; const int mx = 1e5+5; const int mod = 1e9+7; const int x_move[] = {1,-1,0,0,1,1,-1,-1}; const int y_move[] = {0,0,1,-1,1,-1,1,-1}; int n,m; struct node{ int l,r; ll sum,lazy; }T[mx<<6]; int id[mx]; int cnt; void push_up(int rt){ T[rt].sum = T[T[rt].l].sum+T[T[rt].r].sum; } void built(int &rt,int l,int r){ rt = cnt++; T[rt].lazy = 0; if(l==r){ scanf("%lld",&T[rt].sum); return; } int mid = l+r>>1; built(T[rt].l,l,mid); built(T[rt].r,mid+1,r); push_up(rt); } void update(int pre,int &rt,int L,int R,int l,int r,int c){ rt = cnt++; T[rt] = T[pre]; T[rt].sum += 1ll*(r-l+1)*c; if(L>=l&&R<=r){ /// T[rt].sum += 1ll*(R-L+1)*c; // cout<>1; if(l>mid) update(T[pre].r,T[rt].r,mid+1,R,l,r,c); else if(r<=mid) update(T[pre].l,T[rt].l,L,mid,l,r,c); else{ update(T[pre].l,T[rt].l,L,mid,l,mid,c); update(T[pre].r,T[rt].r,mid+1,R,mid+1,r,c); } } ll query(int rt,int L,int R,int l,int r,ll x){ if(L>=l&&R<=r){ // cout<>1; if(l>mid) return query(T[rt].r,mid+1,R,l,r,x+T[rt].lazy); else if(r<=mid) return query(T[rt].l,L,mid,l,r,x+T[rt].lazy); else return query(T[rt].l,L,mid,l,mid,x+T[rt].lazy)+query(T[rt].r,mid+1,R,mid+1,r,x+T[rt].lazy); } int main(){ //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); int t,q,ca = 1; while(scanf("%d%d",&n,&m)!=EOF){ cnt = 1; q = 0; built(id[0],1,n); while(m--){ char op[10]; int l,r,d; scanf("%s",op); if(op[0]=='Q'){ scanf("%d%d",&l,&r); //assert(r>=l); printf("%lld\n",query(id[q],1,n,l,r,0)); } else if(op[0]=='H'){ scanf("%d%d%d",&l,&r,&d); //assert(r>=l); printf("%lld\n",query(id[d],1,n,l,r,0)); } else if(op[0]=='B'){ scanf("%d",&d); q=d; } else{ scanf("%d%d%d",&l,&r,&d); q++; //assert(r>=l); update(id[q-1],id[q],1,n,l,r,d); } } } return 0; }