您的位置:首页 > 其它

线段树专辑——hdu 1540 Tunnel Warfare

2011-11-11 16:46 309 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1540

又是一道跟新查找最大了连续空余区间的题目,由于每次都是炸一个点和修复一个点,所以max_val域都省下了~

由于题目只要求数目,无涉及节点的先后,所以查找的话随便怎么查吧,只要你别遗漏就好了

还有一个要注意的就是一个隧道是可以重复炸毁重复修复的~~

View Code

#include<iostream>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;

struct node
{
int l;
int r;
int l_val;
int r_val;
int cover;
};

node tree[250000];

int max(int a,int b)
{
return a>b?a:b;
}

stack<int>S;
int n,m;

void build(int i,int l,int r)
{
tree[i].l=l;
tree[i].r=r;
tree[i].cover=0;
tree[i].l_val=tree[i].r_val=r-l+1;
if(l==r)
return;
int mid=(l+r)/2;
build(2*i,l,mid);
build(2*i+1,mid+1,r);
}

void fun(int i)
{
if(tree[i].cover==0)
{
tree[i].l_val=tree[i].r_val=tree[i].r-tree[i].l+1;
}
else
{
tree[i].l_val=tree[i].r_val=0;
}
}

void updata(int i,int l,int r,int w)
{
if(tree[i].l>r || tree[i].r<l)
return;
if(tree[i].l>=l && tree[i].r<=r)
{
tree[i].cover=w;
fun(i);
return;
}
if(tree[i].cover!=-1)
{
tree[2*i].cover=tree[2*i+1].cover=tree[i].cover;
fun(2*i);
fun(2*i+1);
tree[i].cover=-1;
}
updata(2*i,l,r,w);
updata(2*i+1,l,r,w);
if(tree[2*i].cover==tree[2*i+1].cover)
tree[i].cover=tree[2*i].cover;
else
tree[i].cover=-1;
tree[i].l_val=tree[2*i].l_val+(tree[2*i].cover==0?tree[2*i+1].l_val:0);
tree[i].r_val=tree[2*i+1].r_val+(tree[2*i+1].cover==0?tree[2*i].r_val:0);
}

int query(int i,int w)
{
if(tree[i].l<=w && tree[i].l+tree[i].l_val-1>=w)  //w点在左边
return tree[i].l_val;
else if(tree[i].r>=w && tree[i].r-tree[i].r_val+1<=w) //w点在右边
return tree[i].r_val;
else if(tree[2*i].r-tree[2*i].r_val+1<=w && tree[2*i+1].l+tree[2*i+1].l_val-1>=w) //w点在中间的连续空闲空间
return tree[2*i].r_val+tree[2*i+1].l_val;
else if(tree[i].l<tree[i].r)  //没找到,则向左右子区间查找
{
int mid=(tree[i].l+tree[i].r)/2;
if(w<=mid)
{
return query(2*i,w);
}
else if(w>mid)
{
return query(2*i+1,w);
}
}
return 0;
}

int main()
{
char c;
int i,a;
freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m)==2)
{
build(1,1,n);
while(!S.empty())
S.pop();
for(i=0;i<m;i++)
{
getchar();
scanf("%c",&c);
if(c=='D')
{
scanf("%d",&a);
S.push(a);
updata(1,a,a,1);
}
else if(c=='R')
{
a=S.top();
S.pop();
updata(1,a,a,0);
}
else
{
scanf("%d",&a);
a=query(1,a);
printf("%d\n",a);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: