线段树(成段更新) 之 poj 3468 A Simple Problem with Integers

//  [7/29/2014 Sjm]
/*
线段树称断更新。。。
关键lazy思想,保存增量,更新时只更新到某一段,不再向下更新,待再次更新或查询到此段时,对其子节点进行更新。。
*/
 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <string>
 6 using namespace std;
 7 typedef __int64 int64;
 8 #define lson l, m, rt<<1
 9 #define rson m+1, r, rt<<1 | 1
10 #define GetMid(l, r) l+((r-l)>>1)
11 
12 const int MAX_N = 100005;
13 int N, Q;
14 int64 Sum[MAX_N << 2], Mark[MAX_N << 2];
15 
16 void PushUp(int rt) { Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1]; }
17 
18 void PushDown(int rt, int len) {
19     if (Mark[rt]) {
20         Mark[rt << 1] += Mark[rt];
21         Mark[rt << 1 | 1] += Mark[rt];
22         Sum[rt << 1] += (len - (len >> 1))*Mark[rt];
23         Sum[rt << 1 | 1] += (len >> 1)*Mark[rt];
24         Mark[rt] = 0;
25     }
26 }
27 
28 void Build(int l, int r, int rt) {
29     Mark[rt] = 0;
30     if (l == r) { scanf("%I64d", &Sum[rt]); return; }
31     int m = GetMid(l, r);
32     Build(lson);
33     Build(rson);
34     PushUp(rt);
35 }
36 
37 void Update(int L, int R, int val, int l, int r, int rt) {
38     if (L <= l && r <= R) {
39         Sum[rt] += ((r - l + 1)*val);
40         Mark[rt] += val;
41         return;
42     }
43     PushDown(rt, (r - l + 1));
44     int m = GetMid(l, r);
45     if (L <= m) Update(L, R, val, lson);
46     if (m < R) Update(L, R, val, rson);
47     PushUp(rt);
48 }
49 
50 int64 Query(int L, int R, int l, int r, int rt) {
51     if (L <= l && r <= R) {
52         return Sum[rt];
53     }
54     PushDown(rt, (r - l + 1));
55     int64 ans = 0;
56     int m = GetMid(l, r);
57     if (L <= m) ans += Query(L, R, lson);
58     if (m < R) ans += Query(L, R, rson);
59     return ans;
60 }
61 
62 int main()
63 {
64     //freopen("input.txt", "r", stdin);
65     //freopen("output.txt", "w", stdout);
66     while (~scanf("%d %d", &N, &Q)) {
67         Build(1, N, 1);
68         char str[2];
69         int L, R, c;
70         while (Q--) {
71             scanf("%s %d %d", str, &L, &R);
72             if ('C' == str[0]) {
73                 scanf("%d", &c);
74                 if (0 == c) { continue; }
75                 Update(L, R, c, 1, N, 1);
76             }
77             else { printf("%I64d
", Query(L, R, 1, N, 1)); }
78         }
79     }
80     return 0;
81 }
原文地址:https://www.cnblogs.com/shijianming/p/4140812.html