题目链接:
http://poj.org/problem?id=3667
题意:
有n个房间,m个询问,询问的第一个数字若为1,输入一个k,表示寻找一段长度为k的连续空房间,若能找到,则输出满足条件的整段房间里,编号最小的房间的编号,并将这k间空房占满,第一个数字若为2,则输入两个数 x,y,表示将区间x~y的房间全部清空成空房间。
题解:
线段树的每个节点存四个信息:
1 . tr[id].L :表示id所代表的区间中,以最左端开头的最长连续空房间的长度。
2.tr[id].R:表示id所代表的区间中,以最右端结尾的最长连续空房间的长度。
3.tr[id].M:表示id所代表的区间中,最长连续空房间的长度。
4.tr[id].lazy:线段树区间操作时常用信息。。。
具体维护信息的方法与查询方法看代码:
代码:
#include
#include
#include
#define lson (id*2)
#define rson (id*2+1)
using namespace std;
struct node{
int L;int R;int M;int lazy;
}tr[300005];
void pushup(int id,int l,int r)
{
int mid=(l+r)/2;
tr[id].M=max(max(tr[lson].M,tr[rson].M),tr[lson].R+tr[rson].L);
if (tr[lson].L==mid-l+1) tr[id].L=tr[lson].L+tr[rson].L;
else tr[id].L=tr[lson].L;
if (tr[rson].R==r-mid) tr[id].R=tr[lson].R+tr[rson].R;
else tr[id].R=tr[rson].R;
}
void pushdown(int id,int l,int r)
{
if (tr[id].lazy!=-1)
{
int mid=(l+r)/2;
tr[lson].R=tr[lson].L=tr[lson].M=tr[id].lazy*(mid-l+1);
tr[rson].R=tr[rson].L=tr[rson].M=tr[id].lazy*(r-mid);
tr[lson].lazy=tr[rson].lazy=tr[id].lazy;
tr[id].lazy=-1;
}
}
void build(int id,int l,int r)
{
tr[id].lazy=-1;
if (l>r) return ;
if (l==r)
{
tr[id].L=1;
tr[id].R=1;
tr[id].M=1;
return ;
}
int mid=(l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(id,l,r);
}
void exc(int id,int l,int r,int L,int R,int v)
{
if (l>r || l>R || rreturn ;
if (l>=L && r<=R)
{
tr[id].L=v*(r-l+1);
tr[id].R=v*(r-l+1);
tr[id].M=v*(r-l+1);
tr[id].lazy=v;
return ;
}
int mid=(l+r)/2;
pushdown(id,l,r);
if (L<=mid) exc(lson,l,mid,L,R,v);
if (R>=mid+1) exc(rson,mid+1,r,L,R,v);
pushup(id,l,r);
}
int query(int id,int l,int r,int k)
{
int mid=(l+r)/2;
pushdown(id,l,r);
if (tr[id].Mreturn 0;
else if (tr[id].L>=k)
return l;
else if (tr[lson].M>=k)
return query(lson,l,mid,k);
else if (tr[lson].R+tr[rson].L>=k)
return mid-tr[lson].R+1;
else
return query(rson,mid+1,r,k);
return 0;
}
int n,m,p,x,y;
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
for (int i=1;i<=m;i++)
{
scanf("%d",&p);
if (p==1)
{
scanf("%d",&x);
int ans=query(1,1,n,x);
if (ans!=0) exc(1,1,n,ans,ans+x-1,0);
printf("%d\n",ans);
}
else
{
scanf("%d%d",&x,&y);
exc(1,1,n,x,x+y-1,1);
}
}
}