Codeforces 219E Parking Lot 线段树
线段树区间合并一下, 求当前要占的位置, 不包括两端点的写起来方便一点。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-6; const double PI = acos(-1); int n, m, tot, pos[1000001]; PII gg[3]; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 struct info { PII mx; int cnt, L, R; } a[N << 2]; info operator + (const info& a, const info& b) { info c; c.cnt = a.cnt + b.cnt; c.mx = max(a.mx, b.mx); c.L = min(a.L, b.L); c.R = max(a.R, b.R); if(a.cnt && b.cnt && a.R + 1 < b.L) { int p = (b.L + a.R) / 2; c.mx = max(c.mx, mk(min(b.L - p, p - a.R), -p)); } return c; } void build(int l, int r, int rt) { if(l == r) { a[rt].cnt = 0; a[rt].L = inf; a[rt].R = -inf; a[rt].mx = mk(0, 0); return; } int mid = l + r >> 1; build(lson); build(rson); a[rt] = a[rt << 1] + a[rt << 1 | 1]; } void update(int p, int op, int l, int r, int rt) { if(l == r) { if(op == 1) { a[rt].cnt = 1; a[rt].L = a[rt].R = p; a[rt].mx = mk(0, 0); } else { a[rt].cnt = 0; a[rt].L = inf; a[rt].R = -inf; a[rt].mx = mk(0, 0); } return; } int mid = l + r >> 1; if(p <= mid) update(p, op, lson); else update(p, op, rson); a[rt] = a[rt << 1] + a[rt << 1 | 1]; } int main() { scanf("%d%d", &n, &m); build(1, n, 1); while(m--) { int op, x; scanf("%d%d", &op, &x); if(op == 1) { tot = 0; if(a[1].mx.se) gg[tot++] = a[1].mx; if(a[1].L != 1 && a[1].cnt) gg[tot++] = mk(a[1].L - 1, -1); if(a[1].R != n && a[1].cnt) gg[tot++] = mk(n - a[1].R, -n); if(!tot) gg[tot++] = mk(inf, -1); sort(gg, gg + tot); reverse(gg, gg + tot); pos[x] = -gg[0].se; update(-gg[0].se, 1, 1, n, 1); printf("%d ", -gg[0].se); } else { update(pos[x], -1, 1, n, 1); } } return 0; } /* */