题目大意:
有一段连续房间,有俩种操作,操作1是寻找最左边的连续的x个空房间的初始位置,操作2是将区间a,b的房间全部都置空;
解题思路:
线段树区间修改和合并,用到了一个懒惰标记cover;
ls从左边第一个开始,连续的空的房间
rs右边最后一个房间结束连续的空的房间
ms为这个区间剩余的最大的连续的空的房间
len为区间的长度;
lc,rc为区间的边界
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 100010
#define L(a) (a)<<1
#define R(a) (a)<<1|1
struct Node{
int lc,rc;
int ls,rs,ms;
int len;
int cover;
}node[3*maxn];
void pushup(int k)
{
node[k].ls=node[L(k)].ls;
node[k].rs=node[R(k)].rs;
if(node[L(k)].ls==node[L(k)].len)
node[k].ls+=node[R(k)].ls;
if(node[R(k)].rs==node[R(k)].len)
node[k].rs+=node[L(k)].rs;
node[k].ms=max(max(node[L(k)].ms,node[R(k)].ms),node[L(k)].rs+node[R(k)].ls);
}
void pushdown(int k)
{
if(node[k].cover!=-1)
{
int len=node[k].rc-node[k].lc+1;
node[L(k)].cover=node[R(k)].cover=node[k].cover;
node[L(k)].ms=node[L(k)].ls=node[L(k)].rs=node[k].cover?0:len-(len>>1);
node[R(k)].ms=node[R(k)].ls=node[R(k)].rs=node[k].cover?0:(len>>1);
node[k].cover=-1;
}
}
void create(int k,int l,int r)
{
node[k].lc=l;
node[k].rc=r;
node[k].ls=node[k].rs=node[k].ms=r-l+1;
node[k].cover=-1;
node[k].len=r-l+1;
if(l==r)
return ;
int mid=(l+r)>>1;
create(L(k),l,mid);
create(R(k),mid+1,r);
}
void updata(int k,int l,int r,int op)
{
if(node[k].lc>=l&&node[k].rc<=r)
{
node[k].ms=node[k].ls=node[k].rs=op?0:node[k].len;
node[k].cover=op;
return ;
}
pushdown(k);
int mid=(node[k].lc+node[k].rc)>>1;
if(r<=mid)
updata(L(k),l,r,op);
else if(l>mid)
updata(R(k),l,r,op);
else
{
updata(L(k),l,mid,op);
updata(R(k),mid+1,r,op);
}
pushup(k);
}
int query(int k,int t)
{
if(node[k].lc==node[k].rc)
return node[k].lc;
pushdown(k);
int mid=(node[k].lc+node[k].rc)>>1;
if(node[L(k)].ms>=t)
return query(L(k),t);
else if(node[L(k)].rs+node[R(k)].ls>=t)
return mid-node[L(k)].rs+1;
else
return query(R(k),t);
}
int main()
{
int n,m;
//freopen("input.txt","r",stdin);
scanf("%d%d",&n,&m);
create(1,1,n);
for(int i=0;i<m;i++)
{
int op,a,b;
scanf("%d",&op);
if(op==1)
{
scanf("%d",&a);
if(node[1].ms<a)
printf("0\n");
else
{
int ans=query(1,a);
printf("%d\n",ans);
updata(1,ans,ans+a-1,1);
}
}
else
{
scanf("%d%d",&a,&b);
updata(1,a,a+b-1,0);
}
}
}