题目:Hotel
题意:区间初始全0。两种操作:将区间某一段置0;查询超过指定长度的区间的最左端点(多个区间则取最左)
第一次做错,错在查询时,只是查询整个区间的最长连续子区间,可题目要求的只是超过一定长度的子区间,而不一定是最长的,所以应按左区间,跨左右区间,右区间的顺序递归查找满足要求的子区间。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MAXN 50000
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int msum[MAXN<<2],lsum[MAXN<<2],rsum[MAXN<<2];
int lable[MAXN<<2],idm[MAXN<<2];
void pushUp(int l,int r,int rt) {//合并子区间
int m=(l+r)>>1;
lsum[rt]=lsum[rt<<1]==m-l+1?m-l+1+lsum[rt<<1|1]:lsum[rt<<1];
rsum[rt]=rsum[rt<<1|1]==r-m?r-m+rsum[rt<<1]:rsum[rt<<1|1];
msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);
// if(msum[rt]==msum[rt<<1]) idm[rt]=idm[rt<<1];
// else if(msum[rt]==rsum[rt<<1]+lsum[rt<<1|1]) idm[rt]=m-rsum[rt<<1]+1;
// else idm[rt]=idm[rt<<1|1];
}
void pushDown(int l,int r,int rt) {//标记下放
if(~lable[rt]) {
int m=(l+r)>>1;
lable[rt<<1]=lable[rt<<1|1]=lable[rt];
msum[rt<<1]=lsum[rt<<1]=rsum[rt<<1]=lable[rt]*(m-l+1);//1清空 0占满
msum[rt<<1|1]=lsum[rt<<1|1]=rsum[rt<<1|1]=lable[rt]*(r-m);
// if(lable[rt]) idm[rt<<1]=l,idm[rt<<1|1]=m+1;
// else idm[rt<<1]=idm[rt<<1|1]=-1;
lable[rt]=-1;
}
}
void build(int l,int r,int rt) {
msum[rt]=lsum[rt]=rsum[rt]=r-l+1;
lable[rt]=-1;
// idm[rt]=l;
if(l==r) return ;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void update(int x,int y,int w,int l,int r,int rt) {
if(x<=l&&r<=y) {
msum[rt]=lsum[rt]=rsum[rt]=w*(r-l+1);
lable[rt]=w;
// idm[rt]=w?l:-1;
return ;
}
pushDown(l,r,rt);
int m=(l+r)>>1;
if(x<=m) update(x,y,w,lson);
if(y>m) update(x,y,w,rson);
pushUp(l,r,rt);
}
//int query(int w,int l,int r,int rt) {//错误的查询方式
// int m=(l+r)>>1;
// if(msum[rt<<1]>=w) return idm[rt<<1];
// if(rsum[rt<<1]+lsum[rt<<1|1]>=w) return m-rsum[rt<<1]+1;
// return idm[rt<<1|1];
//}
int query(int w,int l,int r,int rt) {
if (l == r) return l;
pushDown(l,r,rt);
int m = (l + r) >> 1;
if (msum[rt<<1] >= w) return query(w , lson);
else if (rsum[rt<<1] + lsum[rt<<1|1] >= w) return m - rsum[rt<<1] + 1;
return query(w , rson);
}
int main() {
// ios::sync_with_stdio(false);
int n,m,ins,a,b;
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--) {
cin >> ins;
if(ins==1) {
scanf("%d",&a);
if(msum[1]<a) {puts("0");continue;}
int q=query(a,1,n,1);
printf("%d\n",q);
update(q,q+a-1,0,1,n,1);
}
else {
scanf("%d%d",&a,&b);
update(a,a+b-1,1,1,n,1);
}
}
return 0;
}