题目大意:有一群奶牛去旅店住宿,询问 是否有连续 size个 房间,如果有就住下,当然,每一次如果有多个符合条件的size,那么我们都要选择左端点最小的那个,如果没有就不住,去别的地方,同时会有其他的操作,即 从 pos开始 size个 房间的客人会 退房
思路:线段树 ,节点记录信息为 lsum记录区间左端空白区,rsum记录右端空白区,msum记录区间最大空白区,cover记录标记情况。
update和query都很简单,重点是要怎样 更新 lsum,rsum,和msum
可以看出,msum = max (左儿子msum,右儿子msum,左儿子rsum+右儿子lsum)。 lsum=左儿子lsum ,如果 左儿子lsum包括了左儿子整个区间,那么就要加上
右儿子 lsum 。 rsum=右儿子rsum,如果 右儿子rsum包括了 右儿子整个区间,那么也要将 左儿子rsum加上去。。
#include<iostream>
#include<algorithm>
using namespace std;
#define lson u<<1
#define rson u<<1|1
#define MAXN 50005
#define max(a,b,c) ((a)>(b)?(a)>(c)?(a):(c):(b)>(c)?(b):(c))
struct Node{
int lef,rig;
int lsum,rsum,msum;//lsum记录区间左端空白区,rsum记录右端,msum记录整个区间最大空白区
int cover;//覆盖标记
}T[MAXN<<2];
void Build(int u,int l,int r){
T[u].lef=l;
T[u].rig=r;
T[u].cover=-1;
T[u].lsum=T[u].rsum=T[u].msum=r-l+1;
if(l==r)return;
int mid=(l+r)>>1;
Build(lson,l,mid);
Build(rson,mid+1,r);
}
void PushUp(int u){
int len=T[u].rig-T[u].lef+1;
T[u].lsum=T[lson].lsum;
T[u].rsum=T[rson].rsum;
if(T[u].lsum==(len+1)>>1)T[u].lsum+=T[rson].lsum;
if(T[u].rsum==len>>1)T[u].rsum+=T[lson].rsum;
T[u].msum=max(T[lson].msum,T[rson].msum,T[lson].rsum+T[rson].lsum);
}
void PushDown(int u){
int len=T[u].rig-T[u].lef+1;
if(T[u].cover!=-1){
T[lson].cover=T[rson].cover=T[u].cover;
T[lson].lsum=T[lson].rsum=T[lson].msum=T[u].cover?0:(len+1)>>1;
T[rson].lsum=T[rson].rsum=T[rson].msum=T[u].cover?0:len>>1;
T[u].cover=-1;
}
}
void Update(int u,int l,int r,int color){
int len=T[u].rig-T[u].lef+1;
if(l<=T[u].lef&&T[u].rig<=r){
T[u].lsum=T[u].rsum=T[u].msum=color?0:len;
T[u].cover=color;return;
}
else {
PushDown(u);
if(l<=T[lson].rig)Update(lson,l,r,color);
if(r>=T[rson].lef)Update(rson,l,r,color);
PushUp(u);
}
}
int Query(int u,int size){
if(T[u].lef==T[u].rig)return T[u].lef;
else{
PushDown(u);
if(T[lson].msum>=size)return Query(lson,size);
else if(T[lson].rsum+T[rson].lsum>=size)return T[lson].rig-T[lson].rsum+1;
else return Query(rson,size);
}
}
int main(){
int N,M;
while(~scanf("%d%d",&N,&M)){
int cmd,pos,size;
Build(1,1,N);
while(M--){
scanf("%d",&cmd);
if(cmd==1){
scanf("%d",&size);
if(T[1].msum<size){puts("0");continue;}
pos=Query(1,size);
printf("%d\n",pos);
Update(1,pos,pos+size-1,1);
}
else {
scanf("%d%d",&pos,&size);
Update(1,pos,pos+size-1,0);
}
}
}
}