题意:
中文题
要点:
就是一个单点更新的线段树问题,之前一直用线状数组,现在学了一下线段树,这两个能处理的问题都差不多,线段树好理解一些,基本就是存储将一个区间不断二分,形成一个树,方便查询和更新。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int N = 50000 + 5;
int sum[N << 2];
int pushup(int node)
{
return sum[node] = sum[2 * node] + sum[2 * node + 1];
}
void build(int node, int l, int r)
{
if (l == r)
{
scanf("%d",&sum[node]);
return;
}
int m = (l + r) / 2;
build(2 * node, l, m);
build(2 * node + 1, m + 1, r);
pushup(node);
}
void update(int p, int val, int l, int r,int node)
{
if (l == r)
{
sum[node] += val;
return;
}
int m = (l + r)/2;
if (p <= m)
update(p, val, l, m, 2 * node);
else
update(p, val, m + 1, r, 2 * node + 1);
pushup(node);//回溯更新
}
int query(int ll, int rr, int l, int r, int node)
{
if (ll <= l&&rr >= r)
return sum[node];
int m = (l + r) / 2;
int ans = 0;
if (ll <= m)
ans += query(ll, rr, l, m, 2 * node);
if (rr > m)
ans += query(ll, rr, m + 1, r, 2 * node + 1);
return ans;
}
int main()
{
int t;
char order[100];
scanf("%d", &t);
for(int kase=1;kase<=t;kase++)
{
printf("Case %d:\n", kase);
int n;
scanf("%d", &n);
build(1, 1, n);
while (scanf("%s", order) && order[0] != 'E')
{
int x, y;
scanf("%d%d", &x, &y);
if (order[0] == 'A')
{
update(x, y, 1, n, 1);
}
else if (order[0] == 'S')
{
update(x, -y, 1, n, 1);
}
else if (order[0] == 'Q')
{
int ans=query(x, y, 1, n, 1);
printf("%d\n", ans);
}
}
}
return 0;
}