您的位置:首页 > 其它

hdu1166 敌兵布阵-----(线段树)

2017-10-30 19:00 351 查看
用到了 线段树 ,好厉害的题

这里要用 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: