您的位置:首页 > 其它

HDU 1166 敌兵布阵

2011-01-29 20:10 211 查看
我是用线段树解决的,也可以用树状数组解决。

以前看别人的代码写过一个有离散化的线段树,现在印象模糊了,就在拾起来线段树。

build()建树函数

insert()修改cnt的函数,递归时的每一段都包含该段,所以他们的cnt都一起改变。

query()查询函数,一开始直接返回的是区间[i,i+1]的值。完全没抛弃了线段树的精髓。ORZ。。

#include <iostream>
#define MAX 50000
using namespace std;
struct node{
int l,r,mid,cnt;
}tree[MAX*4];
void build(int l,int r,int num)
{
tree[num].l=l;
tree[num].r=r;
tree[num].mid=(l+r)/2;
tree[num].cnt=0;
if(l+1!=r)
{
int mid=(l+r)/2;
build(l,mid,num<<1);
build(mid,r,(num<<1)+1);
}
}
void insert(int l,int r,int num,int val)
{
tree[num].cnt=tree[num].cnt+val;
if(tree[num].l==l&&tree[num].r==r)
return;
if(r<=tree[num].mid)
insert(l,r,num<<1,val);
else if(l>=tree[num].mid)
insert(l,r,(num<<1)+1,val);
else
{
insert(l,tree[num].mid,num<<1,val);
insert(tree[num].mid,r,(num<<1)+1,val);
}
}
int query(int l,int r,int num)
{
if(tree[num].l==l&&tree[num].r==r)
return tree[num].cnt;
if(r<=tree[num].mid)
query(l,r,num<<1);
else if(l>=tree[num].mid)
query(l,r,(num<<1)+1);
else
return query(l,tree[num].mid,num<<1)+query(tree[num].mid,r,(num<<1)+1);
}
int main()
{
int t,n,i,j,ai,pos,ll,rr;
char ch[10];
scanf("%d",&t);
for(i=1;i<=t;++i)
{
printf("Case %d:/n",i);
scanf(" %d",&n);
build(1,n+1,1);
for(j=1;j<=n;++j)
{
scanf(" %d",&ai);
insert(j,j+1,1,ai);
}
while(1)
{
scanf(" %s",&ch);
if(ch[0]=='A')
{
scanf(" %d %d",&pos,&ai);
insert(pos,pos+1,1,ai);
}
else if(ch[0]=='S')
{
scanf(" %d %d",&pos,&ai);
insert(pos,pos+1,1,-ai);
}
else if(ch[0]=='Q')
{
scanf(" %d %d",&ll,&rr);
printf("%d/n",query(ll,rr+1,1));
}
else if(ch[0]=='E')
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: