1. 程式人生 > >Codeforces 46 D Parking Lot(線段樹區間更新模板題)

Codeforces 46 D Parking Lot(線段樹區間更新模板題)

題目地址
題意:有長度為n米的停車場,停車的要求是要與前面一輛車至少隔a米,和後一輛車至少隔b米(只要符合要求就可以停入,不管之後會不會打破這個要求。PS:我就是想了好久沒有想通),有m個操作,有兩種操作型別:

  1. 1 x 把長度為x米的車停入停車場(一定要符合停車要求)
  2. 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; }