题意:n个阵营,输入n个数,再多次输入,输入A,i,j表示第i增加j个 S,ij表示第i减少j个 Q,i,j表示查询i到j E表示 结束
#include<stdio.h>
int s[200005];
int addlazy[200005];
int a[50005];
void pushdown(int id,int ll,int rr){
int mid=(ll+rr)/2;
int ls=2*id,rs=2*id+1;
addlazy[ls]+=addlazy[id];
addlazy[rs]+=addlazy[id];
s[ls]+=(mid-ll+1)*addlazy[id];
s[rs]+=(rr-mid)*addlazy[id];
addlazy[id]=0;
}
void build(int id,int ll,int rr){
addlazy[id]=0;
if(ll==rr){
s[id]=a[ll];
return;
}
int mid = (ll+rr)/2;
build(2*id,ll,mid);
build(2*id+1,mid+1,rr);
s[id]=s[id*2]+s[id*2+1];
}
int Query(int id,int ll,int rr,int l,int r){
if(l<=ll&&rr<=r){
return s[id];
}
int mid = (ll+rr)/2;
if(r<=mid)
return Query(id*2,ll,mid,l,r);
else if(l>mid)
return Query(id*2+1,mid+1,rr,l,r);
else
return Query(2*id,ll,mid,l,r)+Query(2*id+1,mid+1,rr,l,r);
}
void updataAdd(int id,int ll,int rr,int x,int y){
if(x<=ll&&x>=rr){
s[id]=s[id]+(rr-ll+1)*y;
addlazy[id]+=y;
return;
}
pushdown(id,ll,rr);
int mid = (ll+rr)/2;
if(x<=mid)
updataAdd(id*2,ll,mid,x,y);
else
updataAdd(id*2+1,mid+1,rr,x,y);
s[id]=s[id*2]+s[id*2+1];
}
int main(){
int t;
scanf("%d",&t);
for(int ii=1;ii<=t;ii++){
printf("Case %d:\n",ii);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
build(1,1,n);
char q[10];
while(scanf("%s",q)){
if(q[0]=='E') break;
if(q[0]=='Q'){
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",Query(1,1,n,l,r));
}
if(q[0]=='A'){
int i,j;
scanf("%d%d",&i,&j);
updataAdd(1,1,n,i,j);
}
if(q[0]=='S'){
int i,j;
scanf("%d%d",&i,&j);
updataAdd(1,1,n,i,0-j);
}
}
}
}