线段树基础入门题,裸线段树什么的不解释。
//my 187ms AC
//第一道自己A过去的线段树~
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ls rt<<1
#define rs rt<<1|1
#define lson l,m,ls
#define rson m+1,r,rs
#define sf scanf
#define pf printf
using namespace std;
const int N=50000+10;
int a[N],num[4*N],ans;
void build(int l,int r,int rt){
if(l==r){
num[rt]=a[l];
return;
}
int m=(r+l)>>1;
build(lson);
build(rson);
num[rt]=num[ls]+num[rs];//注意这里要写成这种记忆返回的形式,不能写成点在线
//段内就线段上 +点 ,这样会TLE。
}
void add(int x,int y,int l,int r,int rt){
if(l==r){
if(x==l) num[rt]+=y;
return;
}
int m=(r+l)>>1;
if(x<=m) add(x,y,lson);
if(x>=m+1) add(x,y,rson);
num[rt]=num[ls]+num[rs];
}
void query(int ql,int qr,int l,int r,int rt){
if(ql<=l && qr>=r){
ans+=num[rt];
return;
}
int m=(r+l)>>1;
if(ql<=m) query(ql,qr,lson);
if(qr>=m+1) query(ql,qr,rson);
}
int main()
{
int t,n,i,x,y,q=1;
sf("%d",&t);
while(t--){
sf("%d",&n);
memset(num,0,sizeof(num));
for(i=1;i<=n;i++){
sf("%d",a+i);
}
build(1,n,1);//注意这个写在循环外面!!
//for(i=0;i<4*n;i++)pf("%d ",num[i]);
char s[10];
pf("Case %d:\n",q++);
while(sf("%s",s)!=EOF){
ans=0;
if(s[0]=='E') break;
sf("%d%d",&x,&y);
if(s[0]=='Q') {query(x,y,1,n,1); pf("%d\n",ans);}
if(s[0]=='A') add(x,y,1,n,1);
if(s[0]=='S') add(x,-y,1,n,1);
}
}
return 0;
}