Codeforces 219E Parking Lot 线段树

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;
}

/*
*/
原文地址:https://www.cnblogs.com/CJLHY/p/10539088.html