题目链接:http://hihocoder.com/problemset/problem/1080
对于这种不止一个懒标记的线段树,只要弄清楚各种操作和各种懒标记间的关系就OK了。
我的代码:
1 #include <cstdio> 2 3 using namespace std; 4 5 #define MAXN 100005 6 7 int p[MAXN]; 8 9 struct segNode 10 { 11 int left, right, sum, dd, vv; 12 bool lazy1, lazy2; 13 }; 14 15 struct segTree 16 { 17 segNode t[4*MAXN]; 18 void build(int i, int l, int r) 19 { 20 t[i].left = l; 21 t[i].right = r; 22 t[i].lazy1 = false; 23 t[i].lazy2 = false; 24 t[i].dd = 0; 25 if(l<r) 26 { 27 int m = (l+r)/2; 28 build(2*i, l, m); 29 build(2*i+1, m+1, r); 30 t[i].sum = t[2*i].sum+t[2*i+1].sum; 31 } 32 else t[i].sum = p[l]; 33 } 34 void pushdown(int i) 35 { 36 if(t[i].left<t[i].right) 37 { 38 if(t[i].lazy2) 39 { 40 t[2*i].vv = t[i].vv; 41 t[2*i+1].vv = t[i].vv; 42 t[2*i].sum = (t[2*i].right-t[2*i].left+1)*t[i].vv; 43 t[2*i+1].sum = (t[2*i+1].right-t[2*i+1].left+1)*t[i].vv; 44 t[2*i].dd = 0; 45 t[2*i+1].dd = 0; 46 t[2*i].lazy1 = false; 47 t[2*i+1].lazy1 = false; 48 t[2*i].lazy2 = true; 49 t[2*i+1].lazy2 = true; 50 } 51 else if(t[i].lazy1) 52 { 53 t[2*i].sum += (t[2*i].right-t[2*i].left+1)*t[i].dd; 54 t[2*i+1].sum += (t[2*i+1].right-t[2*i+1].left+1)*t[i].dd; 55 if(t[2*i].lazy2) t[2*i].vv += t[i].dd; 56 else 57 { 58 t[2*i].dd += t[i].dd; 59 t[2*i].lazy1 = true; 60 } 61 if(t[2*i+1].lazy2) t[2*i+1].vv += t[i].dd; 62 else 63 { 64 t[2*i+1].dd += t[i].dd; 65 t[2*i+1].lazy1 = true; 66 } 67 } 68 } 69 t[i].dd = 0; 70 t[i].lazy1 = false; 71 t[i].lazy2 = false; 72 } 73 void update(int i, int op, int l, int r, int v) 74 { 75 pushdown(i); 76 if(t[i].left==l&&t[i].right==r) 77 { 78 if(op) 79 { 80 t[i].vv = v; 81 t[i].dd = 0; 82 t[i].sum = (t[i].right-t[i].left+1)*v; 83 t[i].lazy2 = true; 84 } 85 else 86 { 87 t[i].dd = v; 88 t[i].sum += (t[i].right-t[i].left+1)*v; 89 t[i].lazy1 = true; 90 } 91 } 92 else 93 { 94 int m = (t[i].left+t[i].right)/2; 95 if(r<=m) update(2*i, op, l, r, v); 96 else if(l>m) update(2*i+1, op, l, r, v); 97 else 98 { 99 update(2*i, op, l, m, v); 100 update(2*i+1, op, m+1, r, v); 101 } 102 t[i].sum = t[2*i].sum+t[2*i+1].sum; 103 } 104 } 105 int query(int i, int l, int r) 106 { 107 pushdown(i); 108 if(t[i].left==l&&t[i].right==r) return t[i].sum; 109 int m = (t[i].left+t[i].right)/2; 110 if(r<=m) return query(2*i, l, r); 111 if(l>m) return query(2*i+1, l, r); 112 return query(2*i, l, m)+query(2*i+1, m+1, r); 113 } 114 }tree; 115 116 int main() 117 { 118 int n, m; 119 while(scanf("%d%d", &n, &m)!=EOF) 120 { 121 for(int i=0; i<=n; ++i) scanf("%d", &p[i]); 122 tree.build(1, 0, n); 123 while(m--) 124 { 125 int op, l, r, v; 126 scanf("%d%d%d%d", &op, &l, &r, &v); 127 tree.update(1, op, l, r, v); 128 printf("%d ", tree.query(1, 0, n)); 129 } 130 } 131 return 0; 132 }