代码 #1 #2 AC,其余全WA
//程序算法:线段树
#include <bits/stdc++.h>
using namespace std;
const int N=50010;
struct Node{
int l,r,lazy;
int max,lmax,rmax;
}t[N*4];
void build(int rt,int l,int r)
{
t[rt].l=l,t[rt].r=r;
t[rt].max=t[rt].lmax=t[rt].rmax=r-l+1;
if(l==r)return;
int mid=(l+r)>>1;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
}
//该问题存在两种修改:①预定;②退房
void pushdown(int rt)
{
if(t[rt].lazy==1)
{
t[rt*2].max=t[rt*2].lmax=t[rt*2].rmax=0;
t[rt*2+1].max=t[rt*2+1].lmax=t[rt*2+1].rmax=0;
//房间全部被占满。
t[rt*2].lazy=t[rt*2+1].lazy=1;//下发
}
else if(t[rt].lazy==2)
{
t[rt*2].max=t[rt*2].lmax=t[rt*2].rmax=t[rt*2].r-t[rt*2].l+1;
t[rt*2+1].max=t[rt*2+1].lmax=t[rt*2+1].rmax=t[rt*2+1].r-t[rt*2+1].l+1;
//房间全部空闲。
t[rt*2].lazy=t[rt*2+1].lazy=2;//下发。
}
t[rt].lazy=0;//清除。
}
//区间修改。
void modify(int rt,int l,int r,int v)
{
if(t[rt].l>=l&&t[rt].r<=r)
{
if(v==1)t[rt].max=t[rt].lmax=t[rt].rmax=0;
else t[rt].max=t[rt].lmax=t[rt].rmax=t[rt].r-t[rt].l+1;
t[rt].lazy=v;
return;
}
pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid)modify(rt*2,l,r,v);
if(r>mid)modify(rt*2+1,l,r,v);
t[rt].max=max(max(t[rt*2].max,t[rt*2+1].max),t[rt*2].rmax+t[rt*2+1].lmax);
int llen=t[rt*2].r-t[rt*2].l+1,rlen=t[rt*2+1].r-t[rt*2+1].l+1;
t[rt].lmax=t[rt*2].lmax==llen?llen+t[rt*2+1].lmax:t[rt*2].lmax;
t[rt].rmax=t[rt*2+1].rmax==rlen?rlen+t[rt*2].rmax:t[rt*2+1].rmax;
}
int query(int rt,int x)//x个房间。
{
if(t[rt].max<x)return 0;//无法满足。
if(t[rt].r-t[rt].l+1==x)return t[rt].l;
pushdown(rt);
//优先左边。
if(t[rt*2].max>=x)return query(rt*2,x);
if(t[rt*2].rmax+t[rt*2+1].lmax>=x)return t[rt*2].r-t[rt*2].rmax+1;
if(t[rt*2+1].max>=x)return query(rt*2+1,x);
}
int n,m;
int main()
{
cin>>n>>m;
int cmd,x,y;
build(1,1,n);
for(int i=1;i<=m;i++)
{
cin>>cmd>>x;
if(cmd==1)
{
y=query(1,x);
cout<<y<<endl;
modify(1,y,y+x-1,1);
}
else
{
cin>>y;
modify(1,x,x+y-1,2);
}
}
return 0;
}