一、题目
二、分析
裸的线段树区间查询+修改。
三、AC代码
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define ll long long 8 #define lson l, mid, rt << 1 9 #define rson mid + 1, r, rt << 1 | 1 10 const int MAXN = 1e5 + 3; 11 ll add[MAXN << 2], sum[MAXN << 2]; 12 13 void PushUp(int rt) 14 { 15 sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; 16 return; 17 } 18 19 void PushDown(int ln, int rn, int rt) 20 { 21 if(add[rt]) 22 { 23 sum[rt << 1] += (ll) ln * add[rt]; 24 sum[rt << 1 | 1] += (ll) rn * add[rt]; 25 add[rt << 1] += add[rt]; 26 add[rt << 1 | 1] += add[rt]; 27 add[rt] = 0; 28 } 29 return; 30 } 31 32 void Build(int l, int r, int rt) 33 { 34 add[rt] = 0; 35 if(l == r) 36 { 37 scanf("%lld", &sum[rt]); 38 return; 39 } 40 int mid = (l + r) >> 1; 41 Build(lson); 42 Build(rson); 43 PushUp(rt); 44 return; 45 } 46 47 void Update(int L, int R, int c, int l, int r, int rt) 48 { 49 if(L <= l && r <= R) 50 { 51 add[rt] += c; 52 sum[rt] += (ll)(r - l + 1) * c; 53 return; 54 } 55 int mid = (l + r) >> 1; 56 PushDown(mid - l + 1, r - mid, rt); 57 if(L <= mid) 58 { 59 Update(L, R, c, lson); 60 } 61 if(R > mid) 62 { 63 Update(L, R, c, rson); 64 } 65 PushUp(rt); 66 return; 67 } 68 69 ll Query(int L, int R, int l, int r, int rt) 70 { 71 if(L <= l && r <= R) 72 return sum[rt]; 73 int mid = (l + r) >> 1; 74 PushDown(mid - l + 1, r - mid, rt); 75 ll ans = 0; 76 if(L <= mid) 77 { 78 ans += Query(L, R, lson); 79 } 80 if(R > mid) 81 { 82 ans += Query(L, R, rson); 83 } 84 return ans; 85 } 86 87 int main() 88 { 89 //freopen("input.txt", "r", stdin); 90 int N, Q; 91 scanf("%d %d", &N, &Q); 92 Build(1, N, 1); 93 char s[2]; 94 for(int i = 0; i < Q; i++) 95 { 96 int L, R, C; 97 scanf("%s", s); 98 if(s[0] == 'Q') 99 { 100 scanf("%d %d", &L, &R); 101 printf("%I64d ", Query(L, R, 1, N, 1)); 102 } 103 else 104 { 105 scanf("%d %d %d", &L, &R, &C); 106 Update(L, R, C, 1, N, 1); 107 } 108 } 109 }