用到了 线段树 ,好厉害的题
这里要用 scanf 而不是 cin ,不然会超时的。
参考:http://www.cnblogs.com/TenosDoIt/p/3453089.html
#include <iostream>
#include <cstdio>
using namespace std;
int amount[200000];
/*
l和r表示线段树中该结点的左端点和右端点
root是当前线段树根结点的编号
*/
void build(int l,int r,int root)
{
//创建线段树
int mid;
if(l==r)
{
scanf("%d",&amount[root]);//读入每个兵营的初始人数
return;
}
mid=(l+r)/2;
build(l,mid,2*root); //递归构造左子树
build(mid+1,r,2*root+1); //递归构造右子树
amount[root]=amount[2*root]+amount[2*root+1];
}
/*
i~j是查找范围,
*/
int query(int i,int j,int left,int right,int root)
{
int mid,sum=0;
if((i<=left)&&(right<=j)) //该结点的左右端点包含于查找范围之内
return amount[root];
mid=(left+right)/2;
if(i<=mid)//左子树与查找范围有交集
sum+=query(i,j,left,mid,2*root); //递归查找左子树
if(j>=mid+1)//右子树与查找范围有交集
sum+=query(i,j,mid+1,right,2*root+1);//递归查找右子树
return sum;
}
void updata(int l,int r,int root,int i,int value)
{
int mid;
if(l==r)
{
amount[root]+=value;
return;
}
mid=(l+r)/2;
if(i<=mid)
updata(l,mid,2*root,i,value);
else
updata(mid+1,r,2*root+1,i,value);
amount[root]=amount[2*root]+amount[2*root+1];
}
int main()
{
int T;
scanf("%d",&T);
int Case=1;
while(T--)
{
int n,i,j;
char str[10];
scanf("%d",&n);
build(1,n,1);
printf("Case %d:\n",Case++);
while(scanf("%s",str)!=-1&&str[0]!='E')
{
scanf("%d%d",&i,&j);
if(str[0]=='A')
{
updata(1,n,1,i,j);
}
else if(str[0]=='S')
{
updata(1,n,1,i,-j);
}
else
printf("%d\n",query(i,j,1,n,1));
}
}
return 0;
}