使用线段树的数据结构。
每个节点存3个信息:pre->这个节点维护区间的左端点连续空的房间数
suf->这个节点维护区间的右端点连续空的房间数
len->这个节点维护区间的最长连续空的房间数
update为更新父节点信息
download为下标下放(flag更新)
#include<cstdio>
const int MAXN=50000;
const int MAXM=50000;
const int MAX=1<<18;
int n,m;
int s,pre[MAX+1],suf[MAX+1],len[MAX+1];
int flag[MAX+1];
void open_file(void)
{
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
}
int max(int a,int b)
{
return a>b?a:b;
}
int getint(void)
{
int a;
scanf("%d",&a);
return a;
}
void create_tree(void)
{
s=1;
while(s<n)
s*=2;
}
void download(int i)
{
if(i*2>=s*2)
return;
int a=i*2;
int b=a+1;
if(flag[i]==1)
{
pre[a]=suf[a]=len[a]=pre[b]=suf[b]=len[b]=0;
flag[a]=flag[b]=1;
}
if(flag[i]==2)
{
pre[a]=suf[a]=len[a]=pre[b]=suf[b]=len[b]=len[i]/2;
flag[a]=flag[b]=2;
}
flag[i]=0;
}
void update(int i,int l,int r)
{
int a=i*2;
int b=a+1;
len[i]=max(max(len[a],len[b]),suf[a]+pre[b]);
pre[i]=(len[a]==((l+r)/2-l+1))?len[a]+pre[b]:pre[a];
suf[i]=(len[b]==(r-((l+r)/2+1)+1))?len[b]+suf[a]:suf[b];
}
void fill(int a,int b,bool book,int k,int l,int r)
{
if(r<a||b<l)
return;
if(flag[k])
download(k);
if(a<=l&&r<=b)
{
if(book)
{
pre[k]=suf[k]=len[k]=0;
flag[k]=1;
}
else
{
pre[k]=suf[k]=len[k]=(r-l)+1;
flag[k]=2;
}
return;
}
fill(a,b,book,k*2,l,(l+r)/2);
fill(a,b,book,k*2+1,(l+r)/2+1,r);
update(k,l,r);
}
int query(int k,int d,int l,int r)
{
if(len[k]<d)
return 0;
if(flag[k])
{
download(k);
}
if(k*2<s*2)
{
int a=query(k*2,d,l,(l+r)/2);
if(a)
{
return a;
}
if(suf[k*2]+pre[k*2+1]>=d)
return (l+r)/2-suf[k*2]+1;
a=query(k*2+1,d,(l+r)/2+1,r);
if(a)
{
return a;
}
}
else
return l;
}
void init_solve_output(void)
{
n=getint();
m=getint();
create_tree();
fill(1,n,false,1,1,s);
for(int i=1;i<=m;i++)
{
int t=getint();
if(t==1)
{
int d=getint();
if(len[1]<d)
{
printf("0\n");
}
else
{
int a=query(1,d,1,s);
printf("%d\n",a);
fill(a,a+d-1,true,1,1,s);
}
}
else
{
int x=getint(),d=getint();
fill(x,x+d-1,false,1,1,s);
}
}
}
void close_file(void)
{
fclose(stdin);
fclose(stdout);
}
int main()
{
open_file();
init_solve_output();
close_file();
return 0;
}