Poj3468 线段树 -- 成段更新
线段树----成段更新
题目唯一需要注意的地方是 延迟标志 的那个地方
1 #include <stdio.h> 2 3 #define lson l, m, rt<<1 4 #define rson m+1, r, rt<<1|1 5 6 const int maxn = 100004; 7 8 char cmd[2]; 9 int n, mNum, a, b, c; 10 __int64 sum[maxn<<2]={0}, col[maxn<<2]={0}; 11 12 void BuildTree(int l, int r, int rt) 13 { 14 col[rt] = 0; 15 if (l == r) 16 { 17 scanf("%I64d", &sum[rt]); 18 return ; 19 }/* End of If */ 20 21 int m = (l+r)>>1; 22 BuildTree(lson); 23 BuildTree(rson); 24 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; /* Push Up */ 25 }/* BuildTree */ 26 27 void PushDown(int rt, int k) /* 延迟标志 */ 28 { 29 if (col[rt]) 30 { 31 col[rt<<1] += col[rt]; /* caution,因为col[rt]的更新出错,我WA了好多次 */ 32 col[rt<<1|1] += col[rt]; 33 sum[rt<<1] += col[rt]*(k-(k>>1)); 34 sum[rt<<1|1] += col[rt]*(k>>1); 35 col[rt] = 0; 36 } 37 }/* PushDown */ 38 39 __int64 Query(int L, int R, int l, int r, int rt) 40 { 41 if (L<=l && r<=R) 42 return sum[rt]; 43 44 PushDown(rt, r-l+1); /* Push down */ 45 46 __int64 ret = 0; 47 int m = (l+r)>>1; 48 49 if (L <= m) 50 ret += Query(L, R, lson); 51 if (R > m) 52 ret += Query(L, R, rson); 53 54 return ret; 55 }/* Query */ 56 57 void UpData(int L, int R, int c, int l, int r, int rt) 58 { 59 if (L<=l && r<=R) 60 { 61 col[rt] += c; 62 sum[rt] += c*(r-l+1); 63 64 return ; 65 }/* End of If */ 66 67 PushDown(rt, r-l+1); /* Push down */ 68 69 int m = (l+r)>>1; 70 71 if (L <= m) 72 UpData(L, R, c, lson); 73 if (R > m) 74 UpData(L, R, c, rson); 75 sum[rt] = sum[rt<<1] + sum[rt<<1|1]; /* Push Up */ 76 }/* UpData */ 77 78 int main() 79 { 80 scanf("%d %d", &n, &mNum); 81 82 BuildTree(1, n, 1); 83 for (int i=1; i<=mNum; ++i) 84 { 85 scanf("%s", cmd); 86 if (cmd[0] == 'Q') 87 { /* Query */ 88 scanf("%d %d", &a, &b); 89 printf("%I64d\n", Query(a, b, 1, n, 1)); 90 } 91 else 92 { /* Add */ 93 scanf("%d %d %d", &a, &b, &c); 94 UpData(a, b, c, 1, n, 1); 95 } 96 }/* End of For */ 97 98 return 0; 99 }