제출 #1354579

#제출 시각아이디문제언어결과실행 시간메모리
1354579SulA운세 보기 2 (JOI14_fortune_telling2)C++20
100 / 100
332 ms28012 KiB
#include <bits/stdc++.h>
#define all(a) (a).begin(), (a).end()
using namespace std;

struct segtree {
    vector<int> tree;
    int offset = 1;
    function<int(int, int)> f;
    int I;

    segtree(int n, function<int(int, int)> f, int I) : f(f), I(I) {
        while (offset < n) offset *= 2;
        tree.resize(offset << 1, I);
    }

    void update(int i, int x) {
        i += offset;
        tree[i] = f(tree[i], x);
        while (i >>= 1) tree[i] = f(tree[i*2], tree[i*2 + 1]);
    }

    int query(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr) return tree[v];
        if (qr < l || r < ql) return I;
        int mid = l+r >> 1;
        return f(
                query(v*2, l, mid, ql, qr),
                query(v*2+1, mid+1, r, ql, qr)
                );
    }

    int query(int l, int r) {
        return query(1, 0, offset - 1, l, r);
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    int n,k; cin >> n >> k;
    int a[n], b[n], t[k];
    for (int i = 0; i < n; cin >> a[i] >> b[i++]);
    for (int& x : t) cin >> x;
    vector<int> compress;
    for (int i = 0; i < n; i++)
        compress.push_back(a[i]), compress.push_back(b[i]);
    for (int i = 0; i < k; i++)
        compress.push_back(t[i]);
    sort(all(compress));

    auto comp = [&](int x) {
        return lower_bound(all(compress), x) - compress.begin();
    };

    segtree s(2*n + k, [&](int x, int y) { return max(x, y); }, -1);
    for (int i = 0; i < k; i++) {
        s.update(comp(t[i]), i);
    }
    vector<int> points[k];
    vector<int> final;
    for (int i = 0; i < n; i++) {
        if (a[i] == b[i]) {
            final.push_back(i);
            continue;
        }
        int last = s.query(
                comp(min(a[i], b[i])),
                comp(max(a[i], b[i])) - 1);
        if (last == -1) final.push_back(i);
        else points[last].push_back(i);
    }
    s = segtree(2*n + k, [&](int x, int y) { return x + y; }, 0);
    string res(n, '0');
    for (int i = k-1; i >= 0; i--) {
        for (int j : points[i]) {
            int cnt = s.query(comp(max(a[j], b[j])), 2*n + k - 1);
            res[j] = cnt % 2 ? 'A' : 'B';
            if (a[j] > b[j])
                res[j] ^= 'A' ^ 'B';
        }
        s.update(comp(t[i]), 1);
    }
    for (int j : final) {
        int cnt = s.query(comp(max(a[j], b[j])), 2*n + k - 1);
        res[j] = cnt % 2 ? 'B' : 'A';
    }
    long long sum = 0;
    for (int i = 0; i < n; i++) {
        sum += res[i] == 'A' ? a[i] : b[i];
    }
    cout << sum;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...