题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166
题解:
线段树裸体,注意细节!
代码:
// 线段树
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
const int size = 1000005;
struct _tree {
int l, r, tot;
} seg[size];
int n;
int tot = 0;
void init() {
int i, k;
for ( k = 1; k < n; k <<= 1 );
for ( i = k; i < 2*k; i ++ ) {
seg[i].l = seg[i].r = i-k+1;
seg[i].tot = 0;
}
for ( i = k-1; i > 0; i -- ) {
seg[i].l = seg[2*i].l;
seg[i].r = seg[2*i+1].r;
seg[i].tot = 0;
}
}
void insert(int i, int x, int plus) {
if(seg[i].l <= x && x <= seg[i].r) seg[i].tot += plus;
if(seg[i].l == seg[i].r) return ;
int mid = (seg[i].l+seg[i].r) >> 1;
if(x > mid) insert(i*2+1, x, plus);
else insert(i*2, x, plus);
}
void query(int x, int y, int i) {
if(seg[i].l == x && seg[i].r == y) {
tot += seg[i].tot;
return ;
}
if(seg[i].l == seg[i].r) return ;
int mid = seg[i].l+seg[i].r >> 1;
if(x > mid) query(x, y, 2*i+1);
else if(y <= mid) query(x, y, 2*i);
else {
query(x, mid, 2*i);
query(mid+1, y, 2*i+1);
}
}
int main() {
int tst, cc = 0;
scanf("%d", &tst);
while( tst -- ) {
scanf("%d", &n);
init();
for ( int i = 1; i <= n; i ++ ) {
int k;
scanf("%d", &k);
insert(1, i, k);
}
printf("Case %d:\n", ++cc);
while( true ) {
string a;
int b, c;
cin >> a;
if( a == "End" ) break;
scanf("%d %d", &b, &c);
if( a == "Add" ) {
insert(1, b, c);
} else if( a == "Sub" ) {
insert(1, b, -c);
} else if( a == "Query" ) {
tot = 0;
query(b, c, 1);
printf("%d\n", tot);
}
}
}
return 0;
}