线段树单点更新,区间求和。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#define LL __int64
using namespace std;
const int N=50010;
const int root=1;
struct Node{
int val;
int left,right;
}tree[N*4+100];
int pos[N],n,val[N],ans;
char s[10];
void build(int now,int l,int r){
if(l==r){
tree[now].val=val[l];
tree[now].left=l;
tree[now].right=r;
pos[l]=now;
return ;
}
tree[now].val=0;
tree[now].left=l;
tree[now].right=r;
build(now*2,l,(l+r)/2);
build(now*2+1,(l+r)/2+1,r);
tree[now].val+=(tree[now*2].val+tree[now*2+1].val);
}
void query(int rt,int l,int r){
int L=tree[rt].left,R=tree[rt].right;
if(l<=L&&r>=R){
ans+=tree[rt].val;
return;
}
int m=(L+R)/2;
if(r<=m){
query(rt*2,l,r);
}
else if(l>=m+1){
query(rt*2+1,l,r);
}
else{
query(rt*2,l,r);
query(rt*2+1,l,r);
}
}
void update(int now,int s){
while(now>=root){
tree[now].val+=s;
now/=2;
}
}
int main(){
int T,a,b,t=0;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
memset(pos,0,sizeof(pos));
build(root,1,n);
printf("Case %d:\n",++t);
while(scanf("%s",s)&&strcmp(s,"End")!=0){
scanf("%d%d",&a,&b);
ans=0;
if(strcmp(s,"Query")==0){
query(root,a,b);
printf("%d\n",ans);
}
else{
if(strcmp(s,"Sub")==0)
b=-b;
a=pos[a];
update(a,b);
}
}
}
return 0;
}