初级的单点更新,区间求和
#include<iostream>
const int maxn = 50050;
using namespace std;
struct node
{
int l,r,d;
int mid(){return (l+r)>>1;}
};
node tree[maxn<<2];
void build(int l,int r,int rot)
{
tree[rot].l = l;
tree[rot].r = r;
if(l == r)
{
cin>>tree[rot].d;
return;
}
int mid = tree[rot].mid();
build(l,mid,rot<<1);
build(mid+1,r,rot<<1|1);
tree[rot].d = tree[rot<<1].d+tree[rot<<1|1].d;
}
void updata(int l,int r,int rt,int w,int d)
{
if(l == r)
{
tree[rt].d += d;
return;
}
int mid = tree[rt].mid();
if(w <= mid)
updata(l,mid,rt<<1,w,d);
else
updata(mid+1,r,rt<<1|1,w,d);
tree[rt].d = tree[rt<<1].d+tree[rt<<1|1].d;
}
int query(int l, int r, int rt, int ll,int rr)
{
if(ll<=l&&r<=rr)
return tree[rt].d;
int ans = 0,mid = tree[rt].mid();
if(mid>=ll)//为什么是大于等于
ans += query(l,mid,rt<<1,ll,rr);
if(mid<rr)//为什么是小于
ans += query(mid+1,r,rt<<1|1,ll,rr);
return ans;
}
int main()
{
int t,n,x,y;
char done[10];
scanf("%d",&t);
for(int i = 1; i <= t; i++)
{
scanf("%d",&n);
build(1,n,1);
printf("Case %d:\n",i);
while(scanf("%s",done))
{
if(done[0]=='E')break;
if(done[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",query(1,n,1,x,y));
}
if(done[0]=='A')
{
scanf("%d%d",&x,&y);
updata(1,n,1,x,y);
}
if(done[0]=='S')
{
scanf("%d%d",&x,&y);
updata(1,n,1,x,-y);
}
}
}
return 0;
}