您的位置:首页 > 其它

POJ 1166 敌兵布阵

2014-07-31 18:52 239 查看
这就是一个典型的线段树问题,给一个序列树,让你维护的信息是给定区间上的和,以及对给定某点的值的修改
#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);
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息