题意:区间和

思路:线段树

#include

#include

using namespace std;

#define MAXN 50005

int ans;

struct node{

int left,right,sum;

int mid(){

return (left+right)>>1;

}

}tree[MAXN*4];//注意范围,4倍空间

void btree(int left,int right,int rt){//建树

tree[rt].left=left;

tree[rt].right=right;

if(left==right){

scanf("%d",&tree[rt].sum);

return;

}

int mid=tree[rt].mid();

btree(left,mid,rt<<1);

btree(mid+1,right,rt<<1|1);

tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;//区间里的点数=左区间+右区间

}

void query(int left,int right,int rt,int L,int R){//询问求和

if(L<=left&&right<=R){

ans+=tree[rt].sum;

return;

}

int mid=tree[rt].mid();

if(R<=mid)query(left,mid,rt<<1,L,R);//区间在左子树

else if(L>mid)query(mid+1,right,rt<<1|1,L,R);//区间在右子树

else{

query(left,mid,rt<<1,L,R);

query(mid+1,right,rt<<1|1,L,R);

}

}

void update(int left,int right,int rt,int pos,int add){//单点更新函数

if(left==right){

tree[rt].sum+=add;

return;

}

int mid=tree[rt].mid();

if(pos<=mid)update(left,mid,rt<<1,pos,add);//点在左子树

else update(mid+1,right,rt<<1|1,pos,add);//点在右子树

tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;//区间和更新

}

int main(){

int t,n,a,b,i;

char str[10];

scanf("%d",&t);

for(i=1;i<=t;++i){

printf("Case %d:\n",i);

scanf("%d",&n);

btree(1,n,1);

while(~scanf("%s",str)&&str[0]!='E'){

scanf("%d%d",&a,&b);

if(str[0]=='A')update(1,n,1,a,b);

else if(str[0]=='S')update(1,n,1,a,-b);

else{

ans=0;

query(1,n,1,a,b);

printf("%d\n",ans);

}

}

}

return 0;

}

View Code

 

文章链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。