题目地址
题意:有长度为n米的停车场,停车的要求是要与前面一辆车至少隔a米,和后一辆车至少隔b米(只要符合要求就可以停入,不管之后会不会打破这个要求。PS:我就是想了好久没有想通),有m个操作,有两种操作类型:
- 1 x 把长度为x米的车停入停车场(一定要符合停车要求)
- 2 x 将第x个操作中停入的车开出
思路:把停车场扩建为n+a+b,把每辆车都变为x+a+b来查找,这样就可以直接停车了,但是车子还是只有x的长度,所以在update的时候是用了pos+a~pos+a+y-1(为什么要减一,因为他的边可以重复利用)去更新,但是因为第一辆车多占用了a个,所以输出位置的时候要减去a就是pos了
PS:要这题模板的戳这里
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <cstdio>
#include <algorithm>
#define N 50010
#define LL long long
#define inf 0x3f3f3f3f
#define gol ans<<1
#define gor ans<<1|1
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
using namespace std;
const LL mod = 1e9 + 7;
const double eps = 1e-9;
struct node {
int l, r, lazy;
int llen, rlen, maxlen;
}tree[N<<2];
struct nope {
int l, r;
}now;
map<int, nope> mapp;
struct Segment__Tree {
void pushDown(int ans, int num) {
if (tree[ans].lazy != -1) {
tree[gol].lazy = tree[ans].lazy;
tree[gor].lazy = tree[ans].lazy;
tree[gol].llen = tree[gol].rlen = tree[gol].maxlen = (tree[ans].lazy ? 0 : num - (num >> 1));
tree[gor].llen = tree[gor].rlen = tree[gor].maxlen = (tree[ans].lazy ? 0 : (num >> 1));
tree[ans].lazy = -1;
}
}
void pushUp(int ans, int num) {
tree[ans].llen = tree[gol].llen;
tree[ans].rlen = tree[gor].rlen;
tree[ans].maxlen = max(tree[gol].maxlen, tree[gor].maxlen);
if (tree[ans].llen == num - (num >> 1)) {
tree[ans].llen += tree[gor].llen;
}
if (tree[ans].rlen == num >> 1) {
tree[ans].rlen += tree[gol].rlen;
}
tree[ans].maxlen = max(tree[ans].maxlen, tree[gol].rlen + tree[gor].llen);
}
void build(int l, int r, int ans) {
tree[ans].l = l;
tree[ans].r = r;
tree[ans].lazy = -1;
tree[ans].llen = tree[ans].rlen = tree[ans].maxlen = r - l + 1;
if (l == r) {
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void updata(int l, int r, int ans, int num) {//更新区间
if (l <= tree[ans].l&&r >= tree[ans].r) {
tree[ans].lazy = num;
tree[ans].llen = tree[ans].rlen = tree[ans].maxlen = (num ? 0 : tree[ans].r - tree[ans].l + 1);
return;
}
pushDown(ans, tree[ans].r - tree[ans].l + 1);
int mid = (tree[ans].l + tree[ans].r) >> 1;
if (l <= mid) {
updata(l, r, gol, num);
}
if (mid < r) {
updata(l, r, gor, num);
}
pushUp(ans, tree[ans].r - tree[ans].l + 1);
}
int query(int ans, int num) {//查询长度为num的空闲区间
if (tree[ans].l == tree[ans].r) {
return tree[ans].l;
}
pushDown(ans, tree[ans].r - tree[ans].l + 1);
int mid = (tree[ans].l + tree[ans].r) >> 1;
if (tree[gol].maxlen >= num) {
return query(gol, num);
}
if (tree[gol].rlen + tree[gor].llen >= num) {
return mid - tree[gol].rlen + 1;
}
return query(gor, num);
}
};
int main() {
cin.sync_with_stdio(false);
int n, m;
int a, b;
int x, y;
Segment__Tree trees;
while (cin >> n >> a >> b) {
cin >> m;
mapp.clear();
n = n + a + b;
trees.build(1, n, 1);
for (int i = 1; i <= m; i++) {
cin >> x >> y;
if (x == 1) {
if (tree[1].maxlen < y + a + b) {
cout << -1 << endl;
}
else {
int pos = trees.query(1, y + a + b);
now.l = pos + a;
now.r = now.l + y - 1;
mapp[i]=now;
trees.updata(now.l, now.r, 1, 1);
cout << pos - 1 << endl;
}
}
else {
trees.updata(mapp[y].l, mapp[y].r, 1, 0);
}
}
}
return 0;
}