POJ 3468 - A Simple Problem with Integers
区间加减、查询,有了区间修改的经验,这题还是比较顺利的。
1 #include <cstdio> 2 using namespace std; 3 4 #define recursive_def int l, int r, int i 5 #define lsi i<<1 6 #define rsi lsi | 1 7 #define lso l, m, lsi 8 #define rso m+1, r, rsi 9 #define pushup (v[i] = v[lsi] + v[rsi]) 10 #define pushdown if (dirty[i]) {\ 11 dirty[lsi] += dirty[i], dirty[rsi] += dirty[i]; \ 12 v[lsi] += dirty[i] * (m-l+1); \ 13 v[rsi] += dirty[i] * (r-m); \ 14 dirty[i] = 0;} 15 16 #define MAXV 131072 17 18 long long _v[MAXV<<1], *const v = &_v[-1]; 19 long long _dirty[MAXV << 1], *const dirty = &_dirty[-1]; 20 21 void build(recursive_def) 22 { 23 dirty[i] = 0; 24 if (l == r) scanf("%lld", &v[i]); 25 else { 26 int m = l+r >> 1; 27 build(lso), build(rso); 28 pushup; 29 } 30 } 31 32 int update(int L, int R, int val, recursive_def) 33 { 34 if (L<=l && r<=R) v[i] += (r-l+1) * val, dirty[i] += val; 35 else { 36 int m = l+r >> 1; 37 pushdown; 38 if (L <= m) update(L, R, val, lso); 39 if (m < R) update(L, R, val, rso); 40 pushup; 41 } 42 } 43 44 long long query(int L, int R, recursive_def) 45 { 46 if (L<=l && r<=R) return v[i]; 47 int m = l+r >> 1; 48 pushdown; 49 long long result = 0; 50 if (L <= m) result += query(L, R, lso); 51 if (m < R) result += query(L, R, rso); 52 return result; 53 } 54 55 int main(void) 56 { 57 // freopen("poj3468.txt", "r", stdin); 58 int N, Q; 59 while(scanf("%d%d", &N, &Q) > 0) { 60 build(1, N, 1); 61 while(Q) { 62 int L, R; 63 char op[3]; 64 scanf("\n%s", op); 65 if (op[0] == 'Q') { 66 scanf("%d%d", &L, &R); 67 printf("%lld\n", query(L, R, 1, N, 1)); 68 } else { 69 int C; 70 scanf("%d%d%d", &L, &R, &C); 71 update(L, R, C, 1, N, 1); 72 } 73 --Q; 74 } 75 } 76 return 0; 77 }
3468 | Accepted | 4464K | 2641MS | G++ | 1625B | 2014-06-08 17:04:33 |
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。