题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
一共有三种操作:
- 在第i个节点增加j个人
- 在第i个节点减少j个人
- 查询i, j之间的总人数
一道线段树单点更新的模板题
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson ins<<1
#define rson ins<<1|1
#define merge tree[ins]=tree[lson]+tree[rson]
#define mid (r+l)/2
using namespace std;
const int Max = 50052;
int tree[Max << 2];
int data[Max << 2];
void build(int r, int l, int ins) {
if (l == r) {
tree[ins] = data[l];
} else {
build(r, mid, lson);
build(mid + 1, l, rson);
merge;
}
}
void updata(int l, int r, int ins, int en, int add) {
if (l == r) {
tree[ins] += add;
} else {
if (en <= mid)updata(l, mid, lson, en, add);
else updata(mid + 1, r, rson, en, add);
merge;
}
}
int query(int el, int er, int l, int r, int ins) {
if (el <= l && er >= r)return tree[ins];
else {
int ans = 0;
if (el <= mid)ans += query(el, er, l, mid, lson);
if (er > mid)ans += query(el, er, mid + 1, r, rson);
return ans;
}
}
int main() {
int T, cases = 1;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
for (int a = 1; a <= n; a++) {
scanf("%d", &data[a]);
}
build(1, n, 1);
char opera[10];
int ip, add;
printf("Case %d:\n", cases++);
while (~scanf("%s", opera)) {
if (opera[0] == 'E')break;
scanf("%d%d", &ip, &add);
if (opera[0] == 'A') {
updata(1, n, 1, ip, add);
} else if (opera[0] == 'S') {
updata(1, n, 1, ip, -add);
} else if (opera[0] == 'Q') {
printf("%d\n", query(ip, add, 1, n, 1));
}
}
}
return 0;
}