基本的单点修改区间求和
#include<bits/stdc++.h>
using namespace std;
int ans=0;
struct seg{
int r,l,v;
}tree[200000];
void build(int l,int r,int k) { // l,r是当前线段k所表示的区间。
tree[k].l=l;
tree[k].r=r;
tree[k].v=0;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,2*k);
build(mid+1,r,2*k+1);
}
void add(int num,int v,int k) { // num原数组中的编号,v增加的价值,k第k条线段
if(tree[k].l==tree[k].r&&tree[k].l==num) {
tree[k].v+=v;
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(num<=mid) add(num,v,2*k);
else add(num,v,2*k+1);
tree[k].v=tree[2*k].v+tree[2*k+1].v;
}
void query(int l,int r,int k) {
if(tree[k].l==l&&tree[k].r==r) {
ans+=tree[k].v;
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid) query(l,r,2*k);
else if(l>mid) query(l,r,2*k+1);
else {
query(l,mid,2*k);
query(mid+1,r,2*k+1);
}
}
int main()
{
int t;
int n;
int temp;
char s[11];
int kase=0;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
printf("Case %d:\n",++kase);
build(1,n,1);
for(int i=1;i<=n;i++) {
scanf("%d",&temp);
add(i,temp,1);
}
while(scanf("%s",s)&&s[0]!='E') {
int x,y;
if(s[0]=='A') {
scanf("%d%d",&x,&y);
add(x,y,1);
}
if(s[0]=='S') {
scanf("%d%d",&x,&y);
add(x,-y,1);
}
if(s[0]=='Q') {
ans=0;
scanf("%d%d",&x,&y);
query(x,y,1);
printf("%d\n",ans);
}
}
}
return 0;
}