题目链接:https://vjudge.net/problem/POJ-3667
题目大意
有n个车位,一开始全是空的。m个要求,1 k,表示有k辆车要停,且位置要连续,找到编号最小的位置输出,如果停不下,就输出0;2 x k,表示从x位置开始,有连续k辆车开走。
分析
1代表有空位,0代表没有空位。tr[m].left代表从左端点向右,连续1的区间长度,tr[m].right代表从右端点向左连续1的区间长度,tr[m].all代表整个区间内最长连续1的区间长度。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 50010;
int n, m;
struct node{
int l, r, left, right, all, lazy;
}tr[N<<2];
void pushup(int m)
{
tr[m].left = tr[m<<1].left;
tr[m].right = tr[m<<1|1].right;
if(tr[m<<1].all == tr[m<<1].r - tr[m<<1].l + 1)
tr[m].left += tr[m<<1|1].left;
if(tr[m<<1|1].all == tr[m<<1|1].r - tr[m<<1|1].l + 1)
tr[m].right += tr[m<<1].right;
tr[m].all = max(tr[m<<1].right + tr[m<<1|1].left, max(tr[m<<1].all, tr[m<<1|1].all));
}
void pushdown(int m)
{
if(tr[m].lazy != -1)
{
int val = (tr[m<<1].r - tr[m<<1].l + 1) * tr[m].lazy;
tr[m<<1].left = tr[m<<1].right = tr[m<<1].all = val;
tr[m<<1].lazy = tr[m].lazy;
val = (tr[m<<1|1].r - tr[m<<1|1].l + 1) * tr[m].lazy;
tr[m<<1|1].left = tr[m<<1|1].right = tr[m<<1|1].all = val;
tr[m<<1|1].lazy = tr[m].lazy;
tr[m].lazy = -1;
}
}
void build(int m, int l, int r)
{
tr[m].l = l;
tr[m].r = r;
tr[m].lazy = -1;
tr[m].left = tr[m].right = tr[m].all = (r - l + 1);
if(l == r) return ;
int mid = (l + r) >> 1;
build(m<<1, l, mid);
build(m<<1|1, mid + 1, r);
}
void updata(int m, int l, int r, int val)
{
if(tr[m].l == l && tr[m].r == r)
{
tr[m].lazy = val;
tr[m].left = tr[m].right = tr[m].all = (r - l + 1) * val;
return ;
}
pushdown(m);
int mid = (tr[m].l + tr[m].r) >> 1;
if(r <= mid)
updata(m<<1, l, r, val);
else if(l > mid)
updata(m<<1|1, l, r, val);
else
{
updata(m<<1, l, mid, val);
updata(m<<1|1, mid + 1, r, val);
}
pushup(m);
}
int query(int m, int len)
{
if(tr[m].l == tr[m].r) return tr[m].l;
pushdown(m);
if(tr[m<<1].all >= len)
return query(m<<1, len);
else if(tr[m<<1].right + tr[m<<1|1].left >= len)
return tr[m<<1].r - tr[m<<1].right + 1;
else
return query(m<<1|1, len);
}
int main()
{
while(~scanf("%d %d", &n, &m))
{
build(1, 1, n);
int op;
while(m--)
{
scanf("%d", &op);
if(op == 1)
{
int k;
scanf("%d", &k);
if(tr[1].all < k)
printf("0\n");
else
{
int ans = query(1, k);
printf("%d\n", ans);
updata(1, ans, ans + k - 1, 0);
}
}
else
{
int x, k;
scanf("%d %d", &x, &k);
updata(1, x, x + k - 1, 1);
}
}
}
return 0;
}