Codeforces 46 D Parking Lot(線段樹區間更新模板題)
阿新 • • 發佈:2018-12-24
題目地址
題意:有長度為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;
}