1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| #include <bits/stdc++.h> using namespace std; #define LL long long #define ls rt<<1 #define rs rt<<1|1 #define eps 1e-9 #define mod 1000000007 #define MAXN 1e18 #define MS 100005
int n,m; struct node{ int l,r; LL sum,tag; }p[MS<<5]; int rtpos[MS], tot; int ver;
void push_up(int rt,int l,int r){ p[rt].sum = p[p[rt].l].sum + p[p[rt].r].sum + (LL)(r-l+1)*p[rt].tag; }
int build(int l,int r){ int rt = ++tot; p[rt] = {0,0,0,0}; if(l == r){ cin >> p[rt].sum; return rt; } int m = l+r>>1; p[rt].l = build(l,m); p[rt].r = build(m+1,r); push_up(rt,l,r); return rt; }
int add(int lart,int L,int R,int l,int r,LL val){ int rt = ++tot; p[rt] = p[lart]; if(L <= l && r <= R){ p[rt].sum += (LL)(r-l+1)*val; p[rt].tag += val; return rt; } int m = l+r>>1; if(m >= L) p[rt].l = add(p[lart].l,L,R,l,m,val); if(m < R) p[rt].r = add(p[lart].r,L,R,m+1,r,val); push_up(rt,l,r); return rt; }
LL query(int rt,int L,int R,int l,int r,LL tagsum){ if(L <= l && r <= R){ return p[rt].sum + (LL)(r-l+1)*tagsum; } tagsum += p[rt].tag; int m = l+r>>1; LL ans = 0; if(m >= L) ans += query(p[rt].l,L,R,l,m,tagsum); if(m < R) ans += query(p[rt].r,L,R,m+1,r,tagsum); return ans; }
void solve(){
tot = 0; rtpos[0] = build(1,n); ver = 0; while(m--){ char op; int l,r; LL x; cin >> op; if(op == 'Q'){ cin >> l >> r; cout << query(rtpos[ver],l,r,1,n,0ll) << "\n"; } else if(op == 'C'){ cin >> l >> r >> x; rtpos[ver+1] = add(rtpos[ver],l,r,1,n,x); ver++; } else if(op == 'H'){ cin >> l >> r >> x; cout << query(rtpos[x],l,r,1,n,0ll) << "\n"; } else if(op == 'B'){ cin >> x; ver = x; } } }
int main() { ios::sync_with_stdio(false); int ce; ce = 1;
while(cin >> n >> m){ solve(); }
return 0; }
|