POJ 3468 A Simple Problem with Integers
Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. Each of the next Q lines represents an operation. "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
赤裸裸的线段树
之前看了一点,因为期末考搁了一个月,于是现在就只记得大致思路了。
重写时各种纠结,各种RE、各种WA。
View Code
1 #include <cstdio> 2 3 const int N = 100010; 4 struct Node 5 { 6 int left, right; 7 long long sum, add; 8 } node[N * 6]; 9 int num[N]; 10 11 void CreateTree(int L, int R, int id) 12 { 13 node[id].left = L; 14 node[id].right = R; 15 node[id].add = 0; 16 if (L == R) 17 { 18 node[id].sum = num[L]; 19 return; 20 } 21 int mid = (L + R) / 2; 22 CreateTree(L, mid, 2 * id); 23 CreateTree(mid + 1, R, 2 * id + 1); 24 node[id].sum = node[2 * id].sum + node[2 * id + 1].sum; 25 } 26 27 void Update(int L, int R, int val, int id) 28 { 29 if (node[id].left == L && node[id].right == R) 30 { 31 node[id].add += val; 32 return; 33 } 34 //由于更新区间总是被线段树上的区间完全覆盖 35 //所以这里有R-L <= node[id].right-node[id].left 36 node[id].sum += (R - L + 1) * val; 37 int mid = (node[id].left + node[id].right) / 2; 38 if (R <= mid) 39 { 40 Update(L, R, val, 2 * id); //搜索左子树 41 } 42 else 43 { 44 if (L > mid) 45 { 46 Update(L, R, val, 2 * id + 1); //搜索右子树 47 } 48 else 49 { 50 Update(L, mid, val, 2 * id); 51 Update(mid + 1, R, val, 2 * id + 1); 52 } 53 } 54 } 55 56 long long Find(int L, int R, int id) 57 { 58 //如果检测到当前区间有增量,则加到当前区间的和上 59 //同样该区间的所有子区间都应该有相同的增量,通过维护子区间的add实现 60 if (node[id].add != 0) 61 { 62 node[id].sum += (node[id].right - node[id].left + 1) * node[id].add; 63 node[2 * id].add += node[id].add; 64 node[2 * id + 1].add += node[id].add; 65 node[id].add = 0; 66 } 67 if (node[id].left == L && node[id].right == R) 68 { 69 return node[id].sum; 70 } 71 long long sum = 0; 72 int mid = (node[id].left + node[id].right) / 2; 73 if (R <= mid) 74 { 75 sum += Find(L, R, 2 * id); 76 } 77 else 78 { 79 if (L > mid) 80 { 81 sum += Find(L, R, 2 * id + 1); 82 } 83 else 84 { 85 sum += Find(L, mid, 2 * id) + Find(mid + 1, R, 2 * id + 1); 86 } 87 } 88 return sum; 89 } 90 91 int main() 92 { 93 int n, q; 94 scanf("%d%d", &n, &q); 95 for (int i = 1; i <= n; i++) 96 scanf("%d", &num[i]); 97 CreateTree(1, n, 1); 98 while (q--) 99 { 100 int a, b, w; 101 char opt; 102 scanf("\n%c", &opt); 103 if (opt == 'C') 104 { 105 scanf("%d%d%d", &a, &b, &w); 106 Update(a, b, w, 1); 107 } 108 else 109 { 110 scanf("%d%d", &a, &b); 111 printf("%I64d\n", Find(a, b, 1)); 112 } 113 } 114 return 0; 115 }