直线停车场长度 L ( 10 ≤ L ≤ 1 0 5 ) L(10 \le L \le 10^5) L(10≤L≤105),车长 x x x,头尾还需空出 b , f ( 1 ≤ x ≤ 1000 , 1 ≤ b , f ≤ 100 ) b,f(1\le x \le1000, 1\le b,f \le 100) b,f(1≤x≤1000,1≤b,f≤100)的距离。最多有100次操作:停车和出车操作。对于每个停车操作输出这辆车停的位置(尽量靠左的位置),对于出车操作保证这里车是在停车场内的
100次操作次数似乎可以暴力模拟解决,不过对于区间操作的问题,应该交给线段树,这是带区间更新的线段树模板题。需要注意的细节是查询时区间是 b + x + f b+x+f b+x+f,更新时 b , f b,f b,f可以重合,边界是可以忽略 b , f b,f b,f
#include
#include
#include
using namespace std;
const int maxn = 110000;
int l, b, f;
int a[110], c[110];
int vis[maxn << 2], sum[maxn << 2], lsum[maxn << 2], rsum[maxn << 2];
void build(int l, int r, int node)
{
vis[node] = -1;
lsum[node] = rsum[node] = sum[node] = r - l + 1;
if (l == r) return;
int mid = (l + r) >> 1;
build(l, mid, node << 1);
build(mid + 1, r, node << 1 | 1);
}
void pushdown(int l, int r, int node)
{
int len = r - l + 1;
int lnode = node << 1;
int rnode = lnode | 1;
if (vis[node] != -1)
{
vis[lnode] = vis[rnode] = vis[node];
lsum[lnode] = rsum[lnode] = sum[lnode] = vis[node] ? 0 : len - (len >> 1);
lsum[rnode] = rsum[rnode] = sum[rnode] = vis[node] ? 0 : len >> 1;
vis[node] = -1;
}
}
int query(int a, int l, int r, int node)
{
if (l == r)
return l;
pushdown(l, r, node);
int mid = (l + r) >> 1;
int lnode = node << 1;
int rnode = lnode | 1;
if (sum[lnode] >= a)
return query(a, l, mid, lnode);
else if (rsum[lnode] + lsum[rnode] >= a)
return mid - rsum[lnode] + 1 + b;
else
return query(a, mid + 1, r, rnode);
}
void pushup(int l, int r, int node)
{
int len = r - l + 1;
int lnode = node << 1;
int rnode = lnode | 1;
lsum[node] = lsum[lnode];
rsum[node] = rsum[rnode];
if (lsum[node] == len - (len >> 1))
lsum[node] += lsum[rnode];
if (rsum[node] == (len >> 1))
rsum[node] += rsum[lnode];
sum[node] = max(rsum[lnode] + lsum[rnode], max(sum[lnode], sum[rnode]));
}
void update(int x, int y, int v, int l, int r, int node)
{
if (x <= l && y >= r)
{
lsum[node] = rsum[node] = sum[node] = v ? 0 : r - l + 1;
vis[node] = v;
return ;
}
pushdown(l, r, node);
int mid = (l + r) >> 1;
if (x <= mid)
update(x, y, v, l, mid, node << 1);
if (y > mid)
update(x, y, v, mid + 1, r, node << 1 | 1);
pushup(l, r, node);
}
int main()
{
int n, opt, x, cnt = 0;
while (scanf("%d%d%d", &l, &b, &f) != EOF)
{
l += b + f;
build(1, l, 1);
scanf("%d", &n);
while (n--)
{
scanf("%d", &opt);
cnt++;
if (opt == 1)
{
scanf("%d", a + cnt);
if (sum[1] < a[cnt] + b + f)
printf("-1\n");
else {
c[cnt] = query(a[cnt] + b + f, 1, l, 1);
update(c[cnt], c[cnt] + a[cnt] - 1, 1, 1, l, 1);
printf("%d\n", c[cnt] - 1 - b);
}
} else if (opt == 2)
{
scanf("%d", &x);
update(c[x], c[x] + a[x] - 1, 0, 1, l, 1);
}
}
}
return 0;
}