답안 #499131

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
499131 2021-12-27T09:23:09 Z Stickfish Palembang Bridges (APIO15_bridge) C++17
100 / 100
591 ms 37104 KB
#include <iostream>
#include <vector>
#include <random>
#include <algorithm>
using namespace std;
using ll = long long;

const ll INF = 1.77013e15;

mt19937 rng(time(0));

struct abssm {
    abssm() {
        root = new node();
        root->prior = rng();
        root->x = -INF;
        root->slope = root->y = 0;
    }
    
    ll find_opty() {
        node* nd = find_nonneg(root);
        return nd->y;
    }

    void addabs(ll x) {
        auto [l, r] = split_x(root, x);
        node* nd = find_first(r);
        node* pv = find_last(l);
        if (!nd || nd->x != x) {
            node* nd0 = new node();
            nd0->prior = rng();
            nd0->x = x;
            nd0->y = pv->y + (x - pv->x) * pv->slope;
            nd0->slope = pv->slope;
            r = merge(nd0, r);
        }
        r->lazy_slope += 1;
        r->lazy_y += r->x - x;
        l->lazy_slope += -1;
        l->lazy_y += x - l->x;
        root = merge(l, r);
    }

    void output() {
        output(root);
    }

 private:
    struct node {
        node* l = nullptr;
        node* r = nullptr;
        ll prior;
        ll x;
        ll y;
        ll slope;
        ll lazy_slope = 0;
        ll lazy_y = 0;
    };

    void output(node* nd) {
        if (!nd)
            return;
        push(nd);
        output(nd->l);
        cout << "(" << nd->x << ' ' << nd->y << ' ' << nd->slope << ") ";
        output(nd->r);
    }

    node* root;

    void push(node* nd) {
        if (nd->l) {
            nd->l->lazy_slope += nd->lazy_slope;
            nd->l->lazy_y += (nd->l->x - nd->x) * nd->lazy_slope + nd->lazy_y;
        }
        if (nd->r) {
            nd->r->lazy_slope += nd->lazy_slope;
            nd->r->lazy_y += (nd->r->x - nd->x) * nd->lazy_slope + nd->lazy_y;
        }
        nd->y += nd->lazy_y;
        nd->lazy_y = 0;
        nd->slope += nd->lazy_slope;
        nd->lazy_slope = 0;
    }

    pair<node*, node*> split_x(node* nd, ll x) {
        if (!nd)
            return {nullptr, nullptr};
        push(nd);
        if (x <= nd->x) {
            auto [l, r] = split_x(nd->l, x);
            nd->l = r;
            return {l, nd};
        } else {
            auto [l, r] = split_x(nd->r, x);
            nd->r = l;
            return {nd, r};
        }
    }

    node* merge(node* l, node* r) {
        if (!l && !r)
            return nullptr;
        if (!l) {
            push(r);
            return r;
        }
        if (!r) {
            push(l);
            return l;
        }
        push(l);
        push(r);
        if (l->prior > r->prior) {
            node* lr = merge(l->r, r);
            l->r = lr;
            return l;
        } else {
            node* rl = merge(l, r->l);
            r->l = rl;
            return r;
        }
    }

    node* find_nonneg(node* nd) {
        if (!nd)
            return nullptr;
        push(nd);
        if (nd->slope < 0)
            return find_nonneg(nd->r);
        node* l = find_nonneg(nd->l);
        if (l)
            return l;
        if (nd->slope >= 0)
            return nd;
        return nullptr;
    }

    node* find_first(node* nd) {
        if (!nd)
            return nullptr;
        push(nd);
        if (!nd->l)
            return nd;
        return find_first(nd->l);
    }

    node* find_last(node* nd) {
        if (!nd)
            return nullptr;
        push(nd);
        if (!nd->r)
            return nd;
        return find_last(nd->r);
    }
};

const ll MAXN = 100003;
pair<ll, ll> sg[MAXN];
ll pref_ans[MAXN];
ll suf_ans[MAXN];

signed main() {
    ll k, n = 0;
    ll n0;
    cin >> k >> n0;
    ll addans = 0;
    for (ll i = 0; i < n0; ++i) {
        char c1, c2;
        ll d1, d2;
        cin >> c1 >> d1 >> c2 >> d2;
        if (d1 > d2)
            swap(d1, d2);
        d1 *= 2;
        d2 *= 2;
        if (c1 == c2) {
            addans += d2 - d1;
        } else {
            sg[n] = {(d1 + d2) / 2, (d2 - d1) / 2};
            ++n;
        }
    }
    sort(sg, sg + n);
    //for (ll i = 0; i < n; ++i)
        //cout << "(" << sg[i].first - sg[i].second << ' ' << sg[i].first + sg[i].second << ") ";
    //cout << endl;
    abssm t;
    for (ll i = 0; i < n; ++i) {
        t.addabs(sg[i].first - sg[i].second);
        t.addabs(sg[i].first + sg[i].second);
        //t.output();
        //cout << endl;
        pref_ans[i] = t.find_opty();
    }
    abssm t0;
    for (ll i = n - 1; i >= 0; --i) {
        t0.addabs(sg[i].first - sg[i].second);
        t0.addabs(sg[i].first + sg[i].second);
        suf_ans[i] = t0.find_opty();
    }
    //for (ll i = 0; i < n; ++i) {
        //cout << pref_ans[i] << ' ' << suf_ans[i] << endl;
    //}
    if (k == 1) {
        cout << (pref_ans[n - 1] + addans) / 2 + n << endl;
    } else {
        ll ans = suf_ans[0];
        for (ll i = 0; i < n; ++i) {
            ans = min(ans, pref_ans[i] + suf_ans[i + 1]);
        }
        cout << (ans + addans) / 2 + n << endl;
    }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 4 ms 628 KB Output is correct
5 Correct 4 ms 588 KB Output is correct
6 Correct 1 ms 332 KB Output is correct
7 Correct 3 ms 588 KB Output is correct
8 Correct 3 ms 588 KB Output is correct
9 Correct 3 ms 588 KB Output is correct
10 Correct 1 ms 332 KB Output is correct
11 Correct 2 ms 588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 1 ms 332 KB Output is correct
4 Correct 5 ms 572 KB Output is correct
5 Correct 5 ms 588 KB Output is correct
6 Correct 2 ms 332 KB Output is correct
7 Correct 3 ms 588 KB Output is correct
8 Correct 3 ms 588 KB Output is correct
9 Correct 3 ms 588 KB Output is correct
10 Correct 1 ms 332 KB Output is correct
11 Correct 3 ms 588 KB Output is correct
12 Correct 61 ms 3340 KB Output is correct
13 Correct 581 ms 34660 KB Output is correct
14 Correct 283 ms 4660 KB Output is correct
15 Correct 323 ms 20524 KB Output is correct
16 Correct 85 ms 3328 KB Output is correct
17 Correct 278 ms 34804 KB Output is correct
18 Correct 329 ms 34644 KB Output is correct
19 Correct 300 ms 33152 KB Output is correct
20 Correct 88 ms 3364 KB Output is correct
21 Correct 283 ms 34724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 1 ms 312 KB Output is correct
5 Correct 1 ms 284 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
7 Correct 1 ms 300 KB Output is correct
8 Correct 1 ms 304 KB Output is correct
9 Correct 1 ms 332 KB Output is correct
10 Correct 1 ms 308 KB Output is correct
11 Correct 1 ms 204 KB Output is correct
12 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
4 Correct 0 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Correct 0 ms 204 KB Output is correct
7 Correct 1 ms 304 KB Output is correct
8 Correct 1 ms 332 KB Output is correct
9 Correct 1 ms 332 KB Output is correct
10 Correct 1 ms 332 KB Output is correct
11 Correct 1 ms 308 KB Output is correct
12 Correct 1 ms 332 KB Output is correct
13 Correct 1 ms 332 KB Output is correct
14 Correct 2 ms 332 KB Output is correct
15 Correct 4 ms 588 KB Output is correct
16 Correct 1 ms 332 KB Output is correct
17 Correct 1 ms 332 KB Output is correct
18 Correct 2 ms 332 KB Output is correct
19 Correct 1 ms 332 KB Output is correct
20 Correct 3 ms 576 KB Output is correct
21 Correct 4 ms 604 KB Output is correct
22 Correct 3 ms 588 KB Output is correct
23 Correct 1 ms 328 KB Output is correct
24 Correct 3 ms 588 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 204 KB Output is correct
2 Correct 0 ms 204 KB Output is correct
3 Correct 0 ms 204 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Correct 0 ms 204 KB Output is correct
7 Correct 1 ms 204 KB Output is correct
8 Correct 1 ms 332 KB Output is correct
9 Correct 1 ms 344 KB Output is correct
10 Correct 1 ms 308 KB Output is correct
11 Correct 0 ms 204 KB Output is correct
12 Correct 1 ms 304 KB Output is correct
13 Correct 1 ms 332 KB Output is correct
14 Correct 2 ms 316 KB Output is correct
15 Correct 3 ms 588 KB Output is correct
16 Correct 1 ms 204 KB Output is correct
17 Correct 1 ms 332 KB Output is correct
18 Correct 1 ms 460 KB Output is correct
19 Correct 1 ms 332 KB Output is correct
20 Correct 3 ms 588 KB Output is correct
21 Correct 3 ms 596 KB Output is correct
22 Correct 3 ms 588 KB Output is correct
23 Correct 1 ms 336 KB Output is correct
24 Correct 3 ms 576 KB Output is correct
25 Correct 57 ms 4072 KB Output is correct
26 Correct 122 ms 4360 KB Output is correct
27 Correct 521 ms 33524 KB Output is correct
28 Correct 591 ms 37060 KB Output is correct
29 Correct 589 ms 37104 KB Output is correct
30 Correct 280 ms 19628 KB Output is correct
31 Correct 88 ms 4960 KB Output is correct
32 Correct 287 ms 36944 KB Output is correct
33 Correct 334 ms 36668 KB Output is correct
34 Correct 284 ms 35548 KB Output is correct
35 Correct 89 ms 5232 KB Output is correct
36 Correct 290 ms 36852 KB Output is correct
37 Correct 69 ms 4164 KB Output is correct