题解:树状数组或者线段树都能过,很裸,本人第一次写,代码如下
//树状数组,如下
#include
#include
int c[50005],shu[50005],n;
int low_bit(int x)
{
return x&(-x);
}
void init(int x)
{
int temp=x;
while(temp<=n)
{
shu[temp]+=c[x];
temp+=low_bit(temp);
}
}
void change(int x,int y)
{
while(x<=n)
{
shu[x]+=y;
x+=low_bit(x);
}
}
int sum(int x)
{
int sum=0;
while(x>0)
{
sum+=shu[x];
x-=low_bit(x);
}
return sum;
}
int main()
{
int i,j,t,x,y;
char s[10];
scanf("%d",&t);
for(i=1;i<=t;i++)
{
printf("Case %d:\n",i);
scanf("%d",&n);
for(j=1;j<=n;j++) scanf("%d",c+j);
for(j=1;j<=n;j++) shu[j]=0;
for(j=1;j<=n;j++) init(j);
while(scanf("%s",s),s[0]!='E')
{
scanf("%d%d",&x,&y);
if(s[0]=='A') change(x,y);
else if(s[0]=='S') change(x,(-1)*y);
else if(s[0]=='Q') printf("%d\n",sum(y)-sum(x-1));
}
}
return 0;
}
//线段树,如下
#include
#include
int c[50005],n,s[200500];
void change(int x,int l,int r,int pos,int y)
{
int mid=(l+r)>>1;
if(l==r){ s[x]+=y; return; }
if(pos<=mid) change(2*x,l,mid,pos,y);
else change(2*x+1,mid+1,r,pos,y);
s[x]=s[2*x]+s[2*x+1];
}
int sum(int x,int l,int r,int ltemp,int rtemp)
{
int mid=(l+r)>>1;
if(ltemp<=l&&r<=rtemp) return s[x];
if(rtemp<=mid) return sum(2*x,l,mid,ltemp,rtemp);
else if(ltemp>mid) return sum(2*x+1,mid+1,r,ltemp,rtemp);
return sum(2*x,l,mid,ltemp,mid)+sum(2*x+1,mid+1,r,mid+1,rtemp);
}
void build(int l,int r,int x)
{
int mid=(l+r)>>1;
if(l==r){ s[x]=c[l]; return; }
build(l,mid,2*x);
build(mid+1,r,2*x+1);
s[x]=s[2*x]+s[2*x+1];
}
int main()
{
int i,j,t,x,y;
char s[10];
scanf("%d",&t);
for(i=1;i<=t;i++)
{
printf("Case %d:\n",i);
scanf("%d",&n);
for(j=1;j<=n;j++) scanf("%d",c+j);
build(1,n,1);
while(scanf("%s",s),s[0]!='E')
{
scanf("%d%d",&x,&y);
if(s[0]=='A') change(1,1,n,x,y);
else if(s[0]=='S') change(1,1,n,x,(-1)*y);
else if(s[0]=='Q') printf("%d\n",sum(1,1,n,x,y));
}
}
}