维护一个左起连续空房间的长度ls,右起连续空房间的长度rs,以及一个最大连续空房间数sum。
注意更新子节点后,要更新父节点的cov即lazy值
1032 ms
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define L(t) t << 1
#define R(t) t << 1 | 1
//#define /2 >> 1
//影响时间效率?
using namespace std;
#define N 50010
struct node{
int cov;
int l, r;
int ls, rs, sum;
}Tree[N * 4];
//大小?
void build(int l, int r, int x)
{
Tree[x].l = l;
Tree[x].r = r;
Tree[x].cov = 0;
Tree[x].ls = Tree[x].rs = Tree[x].sum = r - l + 1;
if (l == r)return;
int mid = (l + r) /2;
build(l, mid, L(x));
build(mid + 1, r, R(x));
}
void update_sum(int x)
{
if (Tree[x].cov == 0)
{
Tree[x].sum = Tree[x].ls = Tree[x].rs = Tree[x].r - Tree[x].l + 1;
}
else
{
Tree[x].sum = Tree[x].ls = Tree[x].rs = 0;
}
}
void update_cov(int x)
{
if (Tree[L(x)].cov == 0 && Tree[R(x)].cov == 0)
Tree[x].cov = 0;
else if (Tree[L(x)].cov == 1 && Tree[R(x)].cov == 1)
Tree[x].cov = 1;
else
Tree[x].cov = -1;
}
void update(int l, int r, int cov, int x)
{
if (Tree[x].cov == cov)return;
if (Tree[x].l == l && Tree[x].r == r)
{
Tree[x].cov = cov;
update_sum(x);
return;
}
if (Tree[x].l == Tree[x].r)return;
if (Tree[x].cov != -1)
{
Tree[L(x)].cov = Tree[R(x)].cov = Tree[x].cov;
update_sum(L(x));
update_sum(R(x));
}
int mid = (Tree[x].l + Tree[x].r) /2;
if (l > mid)
update(l, r, cov, R(x));
else if (r <= mid)
update(l, r, cov, L(x));
else
{
update(l, mid, cov, L(x));
update(mid + 1, r, cov, R(x));
}
update_cov(x);
Tree[x].ls = Tree[L(x)].ls + (Tree[L(x)].cov == 0?Tree[R(x)].ls : 0) ;
Tree[x].rs = Tree[R(x)].rs + (Tree[R(x)].cov == 0? Tree[L(x)].rs: 0) ;
Tree[x].sum = max(max(Tree[L(x)].sum, Tree[R(x)].sum), Tree[L(x)].rs + Tree[R(x)].ls);
}
int find(int nu, int x)
{
if (Tree[x].cov == 0 && Tree[x].sum >= nu)
return Tree[x].l;
if (Tree[x].cov == 1)return 0;
if (Tree[L(x)].sum >= nu)
return find(nu, L(x));
if (Tree[L(x)].rs + Tree[R(x)].ls >= nu)
return (Tree[x].l + Tree[x].r) /2 - Tree[L(x)].rs + 1;
if (Tree[R(x)].sum >= nu)
return find(nu, R(x));
return 0;
}
int main()
{
// FILE* fp = fopen("in.txt", "r");
int n, m;
scanf( "%d %d", &n, &m);
build(1, n, 1);
int a, b, c;
while (m--)
{
scanf( "%d", &c);
if (c == 1)
{
scanf( "%d", &a);
int ans = find(a, 1);
printf("%d\n", ans);
if (ans)
update(ans, ans + a - 1, 1, 1);
}
else
{
scanf( "%d %d", &a, &b);
update(a, a + b - 1, 0, 1);
}
}
// getchar();
return 0;
}