地址 http://poj.org/problem?id=3468
线段树模板
要背下此模板
![](http://img.e-com-net.com/image/info8/2b246dbcfe82488397e9aa432bbc4e31.gif)
1 #include2 #include 3 #include 4 #include 5 6 7 using namespace std; 8 9 /* 10 Sample Input 11 10 5 12 1 2 3 4 5 6 7 8 9 10 13 Q 4 4 14 Q 1 10 15 Q 2 4 16 C 3 6 3 17 Q 2 4 18 Sample Output 19 4 20 55 21 9 22 15 23 */ 24 typedef long long ll; 25 26 const int DAT_SIZE = (1 << 18) - 1; 27 28 const int MAX_N = 100000010; 29 30 //输入 31 int N, Q; 32 int A[MAX_N]; 33 char T[MAX_N]; 34 int L[MAX_N], R[MAX_N], X[MAX_N]; 35 36 //线段树 37 ll dat_a[DAT_SIZE], dat_b[DAT_SIZE]; 38 39 //对区间[a,b]同时加x 40 //k是节点的编号 对应的空间是[l,r) 41 void add(int a, int b, int x, int k, int l, int r) 42 { 43 if (a <= l && r <= b) { 44 dat_a[k] += x; 45 } 46 else if (l < b && a < r) { 47 dat_b[k] += (min(b,r)-max(a,l))* x; 48 add(a, b, x, k * 2 + 1, l, (l + r) / 2); 49 add(a, b, x, k * 2 + 2, (l + r) / 2, r); 50 } 51 } 52 53 //计算[a,b)的和 54 //k是节点的编号 对应的区间是[l,r) 55 ll sum(int a, int b, int k, int l, int r) 56 { 57 if (b <= l || r <= a) { 58 return 0; 59 } 60 else if(a <= l && r <= b){ 61 return dat_a[k] * (r - l) + dat_b[k]; 62 } 63 else { 64 ll res = (min(b,r)-max(a,l)) * dat_a[k]; 65 res += sum(a, b, k * 2 + 1, l, (l + r) / 2); 66 res += sum(a, b, k * 2 + 2, (l + r) / 2, r); 67 return res; 68 } 69 } 70 71 void solve() 72 { 73 for (int i = 0; i < N; i++) { 74 add(i, i + 1, A[i], 0, 0, N); 75 } 76 for (int i = 0; i < Q; i++) { 77 if (T[i] == 'C') { 78 add(L[i]-1, R[i] , X[i], 0, 0, N); 79 } 80 else { 81 printf("%lld\n",sum(L[i]-1,R[i],0,0,N)); 82 } 83 } 84 } 85 86 87 88 int main() 89 { 90 cin >> N >> Q; 91 92 for (int i = 0; i < N; i++) { 93 cin >> A[i]; 94 } 95 96 for (int i = 0; i < Q; i++) { 97 cin >> T[i]; 98 if (T[i] == 'C') 99 cin >> L[i] >> R[i] >> X[i]; 100 else 101 cin >> L[i] >> R[i]; 102 } 103 104 solve(); 105 106 return 0; 107 }
![](http://img.e-com-net.com/image/info8/2b246dbcfe82488397e9aa432bbc4e31.gif)
1 #include2 #include 3 4 5 using namespace std; 6 7 /* 8 Sample Input 9 10 5 10 1 2 3 4 5 6 7 8 9 10 11 Q 4 4 12 Q 1 10 13 Q 2 4 14 C 3 6 3 15 Q 2 4 16 Sample Output 17 4 18 55 19 9 20 15 21 */ 22 23 typedef long long ll; 24 25 int n, m; 26 27 const int MAX_N = 1000010; 28 int input[MAX_N]; 29 30 struct Node { 31 int l, r; 32 ll data; 33 }; 34 35 struct Node stree[MAX_N * 4]; 36 37 38 void build(int idx, int l, int r) 39 { 40 stree[idx].l = l; 41 stree[idx].r = r; 42 if (l == r) { 43 //叶子节点 44 stree[idx].data = input[l]; 45 return; 46 } 47 48 int mid = (l + r) / 2; 49 build(idx * 2, l,mid); 50 build(idx * 2 + 1, mid + 1, r); 51 52 stree[idx].data = stree[idx * 2].data + stree[idx * 2 + 1].data; 53 } 54 55 ll query(int idx, int start, int end, int l, int r) 56 { 57 if (l == stree[idx].l && r == stree[idx].r) { 58 return stree[idx].data; 59 } 60 61 int mid = (start + end) / 2; 62 if (l <= mid && r <= mid) { 63 return query(idx * 2, start, mid, l, r); 64 } 65 else if (l > mid && r > mid) { 66 return query(idx * 2 + 1, mid + 1, end, l, r); 67 } 68 else { 69 ll res = 0; 70 res += query(idx * 2 , start, mid, l, mid); 71 res += query(idx * 2 + 1, mid + 1, end, mid + 1, r); 72 return res; 73 } 74 75 } 76 77 void add(int idx, int l, int r, int v) 78 { 79 if (l == r && stree[idx].l == stree[idx].r && stree[idx].l == l) { 80 //叶子节点 81 stree[idx].data += v; 82 return; 83 } 84 85 int mid = (stree[idx].l + stree[idx].r) / 2; 86 if (l <= mid && r <= mid) { 87 add(idx * 2, l, r,v); 88 } 89 else if (l > mid && r > mid) { 90 add(idx * 2 + 1, l, r,v); 91 } 92 else { 93 add(idx * 2 , l, mid, v); 94 add(idx * 2 + 1, mid+1, r, v); 95 } 96 97 stree[idx].data = stree[idx*2].data + stree[idx*2+1].data; 98 } 99 100 101 102 int main() 103 { 104 int n, m; 105 cin >> n >> m; 106 for (int i = 1; i <= n; i++) { 107 cin >> input[i]; 108 } 109 110 build(1, 1, n); 111 112 for (int i = 0; i < m; i++) { 113 char t; 114 int l, r, v; 115 cin >> t; 116 if (t == 'C') { 117 cin >> l >> r >> v; 118 add(1, l, r, v); 119 } 120 else if (t == 'Q') { 121 cin >> l >> r; 122 cout << query(1, 1, n, l, r) << endl; 123 } 124 } 125 126 127 return 0; 128 }