题意:
有N个房间,M次操作。有两种操作
(1)”1 a”,表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示入住。
(2)”2 b len”,把起点为b长度的len的房间清空,即退房。
分析:
明显线段树的题。
lx表示区间左起连续空房的最多间数。
rx表示区间右起连续空房的最多间数。
mx表示区间的最多连续空房间数。
lazy表示整个区间的房间是否被全住满(全是空)
查询的时候:
依次查询端点左边的连续的空闲房间,左子区间的,左子区间和右子区间连接起来,右区间部分是否满足题意。
区间合并:
如果左子区间的lx等于左子区间的len,那么父区间的lmx,除了整个左子区间之外,还要加上右子区间的lmx。右端点的同理。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1001000;
int n,m,x,y,z,k,ans;
struct tree{int l,r,lx,rx,lazy,mx,len;}g[4*N];
int max(int x,int y){return x>y?x:y;}
void build(int rt,int l,int r)
{
g[rt].l=l;
g[rt].r=r;
g[rt].mx=g[rt].lx=g[rt].len=g[rt].rx=r-l+1;
if (l==r) return;
int mid=(l+r)/2;
build(2*rt,l,mid);
build(2*rt+1,mid+1,r);
}
void pushup(int rt)
{
g[rt].lx=g[2*rt].lx;
g[rt].rx=g[2*rt+1].rx;
g[rt].mx=max(g[2*rt].mx,g[2*rt+1].mx);
if (g[2*rt].lx==g[2*rt].len)
g[rt].lx+=g[2*rt+1].lx;
if (g[2*rt+1].rx==g[2*rt+1].len)
g[rt].rx+=g[2*rt].rx;
g[rt].mx=max(g[rt].mx,max(g[rt].lx,g[rt].rx));
g[rt].mx=max(g[rt].mx,g[2*rt].rx+g[2*rt+1].lx);
}
void pushdown(int rt)
{
if (g[rt].lazy==1)
{
g[2*rt].lx=g[2*rt].rx=g[2*rt].mx=0;
g[2*rt+1].lx=g[2*rt+1].rx=g[2*rt+1].mx=0;
g[2*rt].lazy=g[2*rt+1].lazy=g[rt].lazy;
} else
if (g[rt].lazy==-1)
{
g[2*rt].lx=g[2*rt].rx=g[2*rt].mx=g[2*rt].len;
g[2*rt+1].lx=g[2*rt+1].rx=g[2*rt+1].mx=g[2*rt+1].len;
g[2*rt+1].lazy=g[2*rt].lazy=g[rt].lazy;
}
g[rt].lazy=0;
}
void update(int rt,int ll,int rr,int val)
{
int l=g[rt].l,r=g[rt].r;
if (ll<=l && r<=rr)
{
if (val==-1)
g[rt].lx=g[rt].rx=g[rt].mx=r-l+1; else
if (val==1)
g[rt].lx=g[rt].rx=g[rt].mx=0;
g[rt].lazy=val;
return;
}
pushdown(rt);
int mid=(l+r)/2;
if (ll<=mid) update(2*rt,ll,rr,val);
if (rr> mid) update(2*rt+1,ll,rr,val);
pushup(rt);
}
int query(int rt,int k)
{
int l=g[rt].l,r=g[rt].r;
if (l==r) return l;
pushdown(rt);
int res;
if (g[2*rt].mx>=k)
res=query(2*rt,k); else
if (g[2*rt].rx+g[2*rt+1].lx>=k)
res=g[2*rt].r-g[2*rt].rx+1; else
res=query(2*rt+1,k);
pushup(rt);
return res;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,1,n);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if (x==1)
{
ans=0;
if (g[1].mx>=y)
{
ans=query(1,y);
update(1,ans,ans+y-1,1);
}printf("%d\n",ans);
} else
{
scanf("%d",&z);
update(1,y,y+z-1,-1);
}
}
}