这就是一个典型的线段树问题,给一个序列树,让你维护的信息是给定区间上的和,以及对给定某点的值的修改
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define MAX_N 50010
int a[MAX_N];
int tree[MAX_N*4];
//代表敌方工兵营地的数目和指令数目
int n,m;
//构建一颗线段树
void build(int p,int l,int r)
{
if(l==r)
{
tree[p]=a[l];
return ;
}
else{
int mid=(l+r)/2;
build(p*2,l,mid);//构建左子树
build(p*2+1,mid+1,r);//构建右子树
tree[p]=tree[p*2]+tree[p*2+1];
}
}
//改变线段树的元素
void change(int p,int l,int r,int x,int num)
{
if(l==r)
{
tree[p] += num;
return ;
}
else{
int mid=(l+r)/2;
//遍历左子树
if(x<=mid)
change(p*2,l,mid,x,num);
else
//遍历右子树
change(p*2+1,mid+1,r,x,num);
//表示维护的信息是区间和
tree[p] = tree[p*2] + tree[p*2+1];
}
}
//返回在区间x--y上的和
int find(int p,int l,int r,int x,int y)
{
if(x<=l&&y>=r)
{
return tree[p];
}
else{
int ans=0;
int mid=(l+r)/2;
if(y<=mid)
{
return find(p*2,l,mid,x,y);
}
if(x>mid)
{
return find(p*2+1,mid+1,r,x,y);
}
return find(p*2,l,mid,x,mid)+find(p*2+1,mid+1,r,mid+1,y);
}
}
int main()
{
freopen("POJ-1166敌兵布阵.txt","r",stdin);
int t;
scanf("%d",&t);
int k=t;
while(t--)
{
printf("Case %d:\n",k-t);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",a+i);
}
build(1,1,n);
char data[10];
scanf("%s",data);
while(data[0]!='E')
{
int change1;
int location1;
if(data[0]=='A')
{
scanf("%d %d",&location1,&change1);
change(1,1,n,location1,change1);
}
if(data[0]=='S')
{
scanf("%d %d",&location1,&change1);
change(1,1,n,location1,-change1);
}
if(data[0]=='Q')
{
int s, e;
scanf("%d %d",&s,&e);
printf("%d\n",find(1,1,n,s,e));
}
scanf("%s",data);
}
}
}