对于这个题,显然要打lazy标记了,但是lazy标记pushdown的时候肯定会增加一大堆节点,然后就MLE了。(题解这么说的,我其实不会pushdown)
所以,就换另一种方式,把标记直接打到当前区间,把当前区间的父亲节点大小都更新。求区间和的时候把沿途的标记都加起来就可以了。
注意分多钟情况。
——代码
1 #include <cstdio> 2 #define ls son[now][0], l, mid 3 #define rs son[now][1], mid + 1, r 4 #define LL long long 5 6 using namespace std; 7 8 const int N = 5000005; 9 10 int n, m, tot; 11 int rt[N], son[N][2], add[N]; 12 LL sum[N]; 13 14 inline void pushup(int now) 15 { 16 sum[now] = sum[son[now][0]] + sum[son[now][1]]; 17 } 18 19 inline void build(int &now, int l, int r) 20 { 21 now = ++tot; 22 add[now] = 0; 23 if(l == r) 24 { 25 scanf("%lld", &sum[now]); 26 return; 27 } 28 int mid = (l + r) >> 1; 29 build(ls); 30 build(rs); 31 pushup(now); 32 } 33 34 inline void update(int &now, int l, int r, int last, int ql, int qr, int x) 35 { 36 now = ++tot; 37 add[now] = add[last]; 38 sum[now] = sum[last]; 39 son[now][0] = son[last][0]; 40 son[now][1] = son[last][1]; 41 sum[now] += (LL)x * (qr - ql + 1); 42 if(l == ql && r == qr) 43 { 44 add[now] += x; 45 return; 46 } 47 int mid = (l + r) >> 1; 48 if(qr <= mid) update(ls, son[now][0], ql, qr, x); 49 else if(ql > mid) update(rs, son[now][1], ql, qr, x); 50 else 51 { 52 update(ls, son[now][0], ql, mid, x); 53 update(rs, son[now][1], mid + 1, qr, x); 54 } 55 } 56 57 inline LL query(int now, int l, int r, int ql, int qr) 58 { 59 if(l == ql && r == qr) return sum[now]; 60 int mid = (l + r) >> 1; 61 LL ret = (LL)add[now] * (qr - ql + 1); 62 if(qr <= mid) return ret + query(ls, ql, qr); 63 else if(ql > mid) return ret + query(rs, ql, qr); 64 else return ret + query(ls, ql, mid) + query(rs, mid + 1, qr); 65 } 66 67 int main() 68 { 69 int i, x, y, z, now; 70 bool f = 0; 71 char s[5]; 72 while(~scanf("%d %d", &n, &m)) 73 { 74 if(f) printf(" "); 75 else f = 1; 76 now = tot = 0; 77 build(rt[0], 1, n); 78 for(i = 1; i <= m; i++) 79 { 80 scanf("%s", s); 81 switch(s[0]) 82 { 83 case 'C': scanf("%d %d %d", &x, &y, &z); now++; update(rt[now], 1, n, rt[now - 1], x, y, z); break; 84 case 'Q': scanf("%d %d", &x, &y); printf("%lld ", query(rt[now], 1, n, x, y)); break; 85 case 'H': scanf("%d %d %d", &x, &y, &z); printf("%lld ", query(rt[z], 1, n, x, y)); break; 86 case 'B': scanf("%d", &now); break; 87 } 88 } 89 } 90 return 0; 91 }