题目链接:点击打开链接
题目大意:给你n个数字,四种命令,end结束,add i j给第i个数字加j,sub i j给第i个数字减j,query i,j查询i到j区间和
题目思路:纯线段树模板题..搞了几个小时终于可以在不看题解的情况下弄出来了主要参考kuangbin大佬模板,再次感谢
build函数建立线段树。输入也是这个时候。不断的递归拆成两半,直到剩下一个数字就输入,同时递归的时候有加和操作,顺便就完成了线段树的初始化
add函数是给包含第i个数字的所有区间都进行操作。t<=mid就说明第i个数字在区间的中间左边,所以继续add(i<<1,t,s)往左走,反之亦然。
sum查询函数,也是一直拆,遇到在区间内就加起来,到最后全加起来正好是所需要的区间
以下是代码:
#include
#include
#include
using namespace std;
#define MAXN 50005
struct node{
int l,r,sum;
}segTree[MAXN<<2];
void build(int i,int l,int r){
segTree[i].l=l,segTree[i].r=r;
if(l==r){
scanf("%d",&segTree[i].sum);
return;
}
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
}
void add(int i,int t,int s){
segTree[i].sum+=s;
if(segTree[i].l==segTree[i].r){
return;
}
int mid=(segTree[i].l+segTree[i].r)>>1;
if(t<=mid) add(i<<1,t,s);
else add(i<<1|1,t,s);
}
int sum(int i,int l,int r){
if(segTree[i].l==l&&segTree[i].r==r){
return segTree[i].sum;
}
int mid=(segTree[i].l+segTree[i].r)>>1,ans=0;
if(r<=mid) ans=sum(i<<1,l,r);
else if(l>mid) ans=sum(i<<1|1,l,r);
else ans=sum(i<<1,l,mid)+sum(i<<1|1,mid+1,r);
return ans;
}
int main(){
int t,tot=1,n,x,y;
char str[25];
scanf("%d",&t);
while(t--){
scanf("%d",&n);
build(1,1,n);
printf("Case %d:\n",tot++);
while(scanf("%s",str)){
if(str[0]=='E'){
break;
}
scanf("%d%d",&x,&y);
if(str[0]=='A'){
add(1,x,y);
}
else if(str[0]=='S'){
add(1,x,-y);
}
else{
printf("%d\n",sum(1,x,y));
}
}
}
return 0;
}