对应题目hdu–1166
#include <iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=50000+5;
int sum[maxn*4]; //需要开大一点
//建树
void Build_Tree(int l,int r,int rt)
{
if(l==r) //如果l==r,那么是叶子
{
scanf("%d",&sum[rt]); //输入叶子的值
return ;
}
int m=(l+r)>>1; //如果不是,就左右递归
Build_Tree(l,m,rt<<1);
Build_Tree(m+1,r,rt<<1|1);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
//更新树
void update(int p,int add,int l,int r,int rt)
{
if(l==r)
{
sum[rt]+=add; //改变叶子的值
return ;
}
//递归更新其他节点的值
int m=(l+r)>>1;
if(p<=m)
update(p,add,l,m,rt<<1);
else
update(p,add,m+1,r,rt<<1|1);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
int query(int ll,int rr,int l,int r,int rt)
{
if(ll<=l&&rr>=r)return sum[rt]; //当前节点完全包含在查询区间内
int m=(l+r)>>1;
int res=0;
if(ll<=m)res+=query(ll,rr,l,m,rt<<1); //往左走
if(rr>m)res+=query(ll,rr,m+1,r,rt<<1|1); //往右走
return res;
}
int main()
{
int T;
scanf("%d",&T);
int kase=0;
while(T--)
{
int n;
scanf("%d",&n);
Build_Tree(1,n,1);
string s;
printf("Case %d:\n",++kase);
while(cin>>s&&s!="End")
{
int x,y;
scanf("%d%d",&x,&y);
if(s=="Add")
update(x,y,1,n,1);
else if(s=="Sub")
update(x,-y,1,n,1);
else if(s=="Query")
cout<<query(x,y,1,n,1)<<endl;
}
}
}