方法1:线段树
#include <iostream>
#include<algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 55555;
struct node{
int l, r;
int val;
};
int a[MAXN];
node T[MAXN * 4 + 10];
void build(int rt, int begin, int end) {
if(begin == end) {
T[rt].val = a[begin];
T[rt].l = begin;
T[rt].r = end;
}
else {
int mid = (begin + end) >> 1;
build(rt << 1, begin, mid);
build(rt << 1 | 1, mid + 1, end);
T[rt].val = T[rt << 1].val + T[rt << 1 | 1].val;
T[rt].l = begin;
T[rt].r = end;
}
}
void updata(int rt, int id, int add) {
if(T[rt].l == T[rt].r) {
T[rt].val += add;
}
else {
int mid = (T[rt].l + T[rt].r) >> 1;
if(id <= mid) updata(rt << 1, id, add);
else updata(rt << 1 | 1, id, add);
T[rt].val = T[rt << 1].val + T[rt << 1 | 1].val;
}
}
int query(int rt, int l, int r) {
if(T[rt].l >= l && T[rt].r <= r) {
return T[rt].val;
}
else {
int mid = (T[rt].l + T[rt].r) >> 1;
if(r <= mid) return query(rt << 1, l, r);
else if(l > mid) return query(rt << 1 | 1, l, r);
else return query(rt << 1, l, mid) + query(rt << 1 | 1, mid + 1, r);
}
}
int main() {
//freopen("input.txt", "r", stdin);
int T;
scanf("%d", &T);
int N;
int j;
for(j = 1; j <= T; j++) {
printf("Case %d:\n", j);
scanf("%d", &N);
int i;
for(i = 1; i <= N; i++) {
scanf("%d", a + i);
}
build(1, 1, N);
char str[10];
int x, y;
while(1) {
scanf("%s", str);
if(str[0] == 'E') break; //此处注意runtime error
scanf("%d %d", &x, &y);
if(str[0] == 'Q') {
printf("%d\n", query(1, x, y));
}
else if(str[0] == 'A') {
updata(1, x, y);
}
else {
updata(1, x, -y);
}
}
}
return 0;
}
方法2: 树状数组
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 50005;
int sum[maxn], N;
int lowbit(int x) {
return x & (-x);
}
void update(int index, int val) {
int i;
for(i = index; i <= N; i += lowbit(i)) {
sum[i] += val;
}
}
int getsum(int index) {
int i;
int res = 0;
for(i = index; i > 0; i -= lowbit(i)) {
res += sum[i];
}
return res;
}
int main() {
int T;
int kase = 1;
scanf("%d", &T);
while(T--) {
printf("Case %d:\n", kase++);
scanf("%d", &N);
memset(sum, 0, sizeof(sum));
int i, tmp;
for(i = 1; i <= N; i++) {
scanf("%d", &tmp);
update(i, tmp);
}
string str;
int n, m;
while (cin >> str) {
if (str == "End") break;
scanf("%d%d", &n, &m);
if (str == "Query")
printf("%d\n", getsum(m) - getsum(n - 1));
else if (str == "Add")
update(n, m);
else update(n, -m);
}
}
return 0;
}