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\n", -gg[0].se);

        } else {
            update(pos[x], -1, 1, n, 1);
        }
    }
    return 0;
}

/*
*/

 

转载于:https://www.cnblogs.com/CJLHY/p/10539088.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值