题意:
有一条长度为L的街道,有N个操作,现在有两种操作:
(1)”1 a”,表示有一辆长度为a的车开进来想找停车位;
停车位必须满足与它前面的车距离至少为b,与后面的车距离至少为f;
如果能找到这样的停车位,输出这辆车的起始位置(且这个位置最小),否则输出-1;
(2)”2 a”,表示第a个事件里进来停车的那辆车开出去了;
解析:
这题和POJ 3677 Hotel差不多,都是寻找连续的空位。
不过要注意第一辆车是不需要考虑前方车距的,最后一辆车不需要后方车距。
我们可以把街道长度扩充为 L+b+f 即可,假设车长为 x ,那么每次查询长度大于等于x+b+f 的空位就行了。
my code
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define ls (o<<1)
#define rs (o<<1|1)
#define lson ls, L, M
#define rson rs, M+1, R
#define MID (L + R) >> 1
#define LEN(L, R) ((R) - (L) + 1)
#define pb push_back
using namespace std;
typedef pair<int, int> pii;
const int N = 100105;
int cov[N<<2];
int mx[N<<2], mxL[N<<2], mxR[N<<2];
vector<pii> list;
void maintain(int o, int L, int R, int val) {
cov[o] = val;
mx[o] = mxL[o] = mxR[o] = val * LEN(L, R);
}
void pushUp(int o, int L, int R) {
int M = MID;
mxL[o] = mxL[ls], mxR[o] = mxR[rs];
mx[o] = max(mx[ls], max(mx[rs], mxR[ls] + mxL[rs]));
if(mxL[ls] == LEN(L, M)) mxL[o] += mxL[rs];
if(mxR[rs] == LEN(M+1, R)) mxR[o] += mxR[ls];
if(cov[ls] == cov[rs])
cov[o] = cov[ls];
else cov[o] = -1;
}
void pushDown(int o, int L, int R) {
if(cov[o] != -1) {
int M = MID;
maintain(lson, cov[o]);
maintain(rson, cov[o]);
cov[o] = -1;
}
}
void build(int o, int L, int R) {
cov[o] = -1;
if(L == R) {
maintain(o, L, R, 1);
return ;
}
int M = MID;
build(lson);
build(rson);
pushUp(o, L, R);
}
int query(int o, int L, int R, int need) {
if(L == R) return L;
int M = MID;
pushDown(o, L, R);
if(mx[ls] >= need)
return query(lson, need);
else if(mxR[ls] + mxL[rs] >= need)
return M - mxR[ls] + 1;
else
return query(rson, need);
}
void modify(int o, int L, int R, int ql, int qr, int val) {
if(ql <= L && R <= qr) {
maintain(o, L, R, val);
return ;
}
int M = MID;
pushDown(o, L, R);
if(ql <= M) modify(lson, ql, qr, val);
if(qr > M) modify(rson, ql, qr, val);
pushUp(o, L, R);
}
int n, m;
int main() {
int L, b, f;
int op, x, ql, qr;
int start;
while(~scanf("%d%d%d", &L, &b, &f)) {
list.clear();
n = L + b + f;
build(1, 0, n);
scanf("%d", &m);
while(m--) {
scanf("%d%d", &op, &x);
if(op == 1) {
int need = x + b + f;
start = query(1, 0, n, need);
ql = start + b, qr = ql + x - 1;
list.pb(make_pair(ql, qr));
if(b <= ql && qr < b + L) {
printf("%d\n", start);
modify(1, 0, n, ql, qr, 0);
}else {
puts("-1");
}
}else {
ql = list[x-1].first, qr = list[x-1].second;
list.pb(make_pair(ql, qr));
modify(1, 0, n, ql, qr, 1);
}
}
}
}