题意:
1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
2 a b:将[a,a+b-1]的房间清空
原文:https://blog.youkuaiyun.com/fallen_fall/article/details/12974071
查询的时候要能直接获取区间的最大连续空房间,这样就能判断能不能连续放下这x个人,但这样还确定不了具体放哪。放的位置有三种情况1.放在左儿子那个区间。2.放在右儿子那个区间。3.放在左右儿子中间,就是占用左区间的右部分和右区间的左部分。
这样就需要用sum保存整个区间最大的连续段,lsum保存从左端开始的最大连续段,rsum保存右端开始的最大连续段
用一个标记mark表示区间状态,0:区间全空。1:区间全满。-1:当前区间已初始化,不用向下更新
#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 50005
using namespace std;
struct Node{int l,r,lsum,rsum,sum,tag;}t[N<<2];
int n,m;
int read(){
int cnt=0,f=1;char ch=0;
while(!isdigit(ch)){ch=getchar();if(ch=='-')f=-1;}
while(isdigit(ch)) cnt=cnt*10+(ch-'0'),ch=getchar();
return cnt;
}
int len(int x){return t[x].r-t[x].l+1;}
void Pushup(int x){
t[x].lsum = t[x<<1].lsum;
if(t[x].lsum == len(x<<1)) t[x].lsum = t[x<<1].sum + t[x<<1|1].lsum;
t[x].rsum = t[x<<1|1].rsum;
if(t[x].rsum == len(x<<1|1)) t[x].rsum = t[x<<1|1].sum + t[x<<1].rsum;
t[x].sum = max(max(t[x<<1].sum , t[x<<1|1].sum) , t[x<<1].rsum+t[x<<1|1].lsum);
}
void Pushdown(int x){
if(t[x].tag!=-1){
t[x<<1].tag = t[x<<1|1].tag = t[x].tag;
t[x<<1].sum = t[x<<1].lsum = t[x<<1].rsum = t[x].tag*len(x<<1);
t[x<<1|1].sum = t[x<<1|1].lsum = t[x<<1|1].rsum = t[x].tag*len(x<<1|1);
t[x].tag=-1;
}
}
void build(int x,int l,int r){
t[x].l=l , t[x].r=r , t[x].tag=-1;
t[x].lsum = t[x].rsum = t[x].sum = r-l+1;
if(l==r) return;
int mid=l+r>>1;
build(x<<1,l,mid),build(x<<1|1,mid+1,r);
}
int quary(int x,int val){
if(t[x].l==t[x].r) return t[x].l;
Pushdown(x);
if(val<=t[x<<1].sum) return quary(x<<1,val);
else if(val<=t[x<<1].rsum+t[x<<1|1].lsum) return ((t[x].l+t[x].r)>>1) - t[x<<1].rsum + 1;
else return quary(x<<1|1,val);
return 0;
}
void update(int x,int L,int R,int op){
if(L<=t[x].l && t[x].r<=R){
t[x].tag=op;
t[x].sum = t[x].lsum = t[x].rsum = len(x)*op;
return;
}
Pushdown(x);
int mid=t[x].l+t[x].r>>1;
if(L<=mid) update(x<<1,L,R,op);
if(R>mid) update(x<<1|1,L,R,op);
Pushup(x);
}
int main(){
n=read(),m=read(); build(1,1,n);
while(m--){
int op=read();
if(op==1){
int x=read();
if(t[1].sum<x){printf("0\n");continue;}
int p=quary(1,x);
printf("%d\n",p);
update(1,p,p+x-1,0);
}
else{
int x=read(),d=read();
update(1,x,x+d-1,1);
}
}
return 0;
}