【题意】:给出n个兵营,每个兵营初始都有一定数量的士兵,兵营的士兵数量会改变,不定时查询第i个兵营到第j个兵营的士兵数量,输出每次询问的结果。(n <= 50000)

【题解】:很简单的一道数据结构题目。
               这种题目如果能用树状数组最好就用,因为树状数组太容易写了。
               最近在学线段树,所以两种版本的都写了一次。

【代码】:

   【树状数组】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 using namespace std;
 8 #define pb push_back
 9 #define maxn 50005
10 #define lowbit(x) (x & (-x))
11 int val[maxn], n;
12 
13 void add(int x, int e) {
14     for(int i = x; i < maxn; i += lowbit(i)) {
15         val[i] += e;
16     }
17 }
18 
19 int sum(int x) {
20     int res = 0;
21     for(int i = x; i; i -= lowbit(i)) {
22         res += val[i];
23     }
24     return res;
25 }
26 
27 int main() {
28     int T, Case = 1, e, a, b;
29     char str[10];
30     scanf("%d", &T);
31     while(T--) {
32         scanf("%d", &n);
33         memset(val, 0, sizeof(val));
34         for(int i = 1; i <= n; i++) {
35             scanf("%d", &e);
36             add(i, e);
37         }
38         printf("Case %d:\n", Case++);
39         while(1) {
40             scanf("%s", str);
41             if(str[0] == 'E') break;
42             else {
43                 scanf("%d%d", &a, &b);
44                 if(str[0] == 'Q') printf("%d\n", sum(b) - sum(a - 1));
45                 else if(str[0] == 'A') add(a, b);
46                 else add(a, -b);
47             }
48         }
49     }
50     return 0;
51 }

   【线段树】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "vector"
 6 #include "queue"
 7 using namespace std;
 8 #define pb push_back
 9 #define lc(x) (x << 1)
10 #define rc(x) (x << 1 | 1)
11 #define MAX 50005
12 int seg[MAX<<2];
13 int n;
14 void pushup(int p) {
15     seg[p] = seg[lc(p)] + seg[rc(p)];
16 }
17 
18 void build(int l, int r, int p) {
19     if(l == r) {
20         scanf("%d", &seg[p]);
21         return;
22     }
23     int mid = (l + r) >> 1;
24     build(l, mid, lc(p));
25     build(mid + 1, r, rc(p));
26     pushup(p);
27 }
28 
29 int query(int L, int R, int l, int r, int p) {
30     if(L == l && R == r) return seg[p];
31     int mid = (l + r) >> 1;
32     if(L > mid) return query(L, R, mid + 1, r, rc(p));
33     else if(R <= mid) return query(L, R, l, mid, lc(p));
34     else return query(L, mid, l, mid, lc(p)) + query(mid + 1, R, mid + 1, r, rc(p));
35 }
36 
37 void update(int x, int val, int l, int r, int p) {
38     if(l == r) {
39         seg[p] += val;
40         return;
41     }
42     int mid = (l + r) >> 1;
43     if(x <= mid) update(x, val, l, mid, lc(p));
44     else update(x, val, mid + 1, r, rc(p));
45     pushup(p);
46 }
47 
48 int main() {
49     int T, Case = 1, a, b;
50     char str[10];
51     scanf("%d", &T);
52     while(T--) {
53         scanf("%d", &n);
54         build(1, n, 1);
55         printf("Case %d:\n", Case++);
56         while(1) {
57             scanf("%s", str);
58             if(str[0] == 'E') break;
59             else {
60                 scanf("%d%d", &a, &b);
61                 if(str[0] == 'Q') printf("%d\n", query(a, b, 1, n, 1));
62                 else if(str[0] == 'A') update(a, b, 1, n, 1);
63                 else update(a, -b, 1, n, 1);
64             }
65         }
66     }
67     return 0;
68 }