线段树维护区间最长连续1,区间前缀最长连续1,后缀最长连续1
在查询的时候看这个区间的最长长度是否>=d
如果>=d,则先看左子树是否>=d,若否看跨区间的是否>=d,若否再找右子树
再支持一下区间赋值即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <iomanip>
#include <ctime>
#include <climits>
#include <cctype>
#include <algorithm>
#define clr(x) memset(x,0,sizeof(x))
#define LL long long
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
using namespace std;
const int maxn = 50050;
int n,m,range,l,w,len,index;
template <class T> inline void read(T &x) {
int flag = 1; x = 0;
char ch = getchar();
while(ch < '0' || ch > '9') { if(ch == '-') flag = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') { x = (x<<1)+(x<<3)+ch-'0'; ch = getchar(); }
x *= flag;
}
struct node {
int l,r,mark,tlen,llen,rlen;
int mid() { return (l+r)>>1; }
int cal_len() { return r-l+1; }
void updata_len() { tlen = llen = rlen = ( mark ? 0 : cal_len()); }
} t[maxn<<2];
void build(int l, int r, int rt) {
t[rt].l = l, t[rt].r = r,
t[rt].tlen = t[rt].llen = t[rt].rlen = t[rt].cal_len(),
t[rt].mark = 0;
if(l == r) return ;
int mid = t[rt].mid();
build(l, mid, lch(rt));
build(mid+1, r, rch(rt));
return ;
}
int query(int w, int rt) {
if(t[rt].l == t[rt].r && w == 1) return t[rt].l;
if(t[rt].mark != -1) {
t[lch(rt)].mark = t[rch(rt)].mark = t[rt].mark, t[rt].mark = -1;
t[lch(rt)].updata_len(); t[rch(rt)].updata_len();
}
if(t[lch(rt)].tlen >= w) return query(w, lch(rt));
else if(t[lch(rt)].rlen+t[rch(rt)].llen >= w) return (t[lch(rt)].r-t[lch(rt)].rlen+1);
else if(t[rch(rt)].tlen >= w) return query(w, rch(rt));
else return 0;
}
void updata(int l, int r, int val, int rt) {
if(t[rt].l == l && t[rt].r == r) { t[rt].mark = val; t[rt].updata_len(); return ; }
if(t[rt].mark != -1) {
t[lch(rt)].mark = t[rch(rt)].mark = t[rt].mark, t[rt].mark = -1;
t[lch(rt)].updata_len(), t[rch(rt)].updata_len();
}
int mid = t[rt].mid();
if(l > mid) updata(l, r, val, rch(rt));
else if(r <= mid) updata(l, r, val, lch(rt));
else updata(l, mid, val, lch(rt)), updata(mid+1, r, val, rch(rt));
int tmp = max(t[lch(rt)].tlen, t[rch(rt)].tlen);
t[rt].tlen = max(tmp,t[lch(rt)].rlen+t[rch(rt)].llen),
t[rt].llen = t[lch(rt)].llen, t[rt].rlen = t[rch(rt)].rlen;
if(t[lch(rt)].tlen == t[lch(rt)].cal_len()) t[rt].llen += t[rch(rt)].llen;
if(t[rch(rt)].tlen == t[rch(rt)].cal_len()) t[rt].rlen += t[lch(rt)].rlen;
return ;
}
int main() {
freopen("hotel.in","r",stdin);
freopen("hotel.out","w",stdout);
int n,m;
read(n); read(m);
build(1, n, 1);
while(m--) {
read(range);
if(range&1) {
read(w); index = query(w, 1);
printf("%d\n",index);
if(index) updata(index, index+w-1, 1, 1);
}
else read(l), read(len), updata(l, l+len-1, 0, 1);
}
return 0;
}