| # | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 | 
|---|---|---|---|---|---|---|---|
| 1201937 | Triseedot | 식물 비교 (IOI20_plants) | C++20 | 0 ms | 0 KiB | 
#include "plants.h"
#include <bits/stdc++.h>
using namespace std;
#define len(v) (int) (v.size())
#define all(v) v.begin(), v.end()
using i32 = int;
#define int long long
struct SegmentTree {
    int n;
    vector<pair<int, int>> tree;
    vector<int> push;
    const pair<int, int> NEUTRAL = {1e9, -1};
    void receive_update(int v, int upd) {
        tree[v].first += upd;
        push[v] += upd;
    }
    void do_push(int v) {
        receive_update(2 * v, push[v]);
        receive_update(2 * v + 1, push[v]);
        push[v] = 0;
    }
    void build(int v, int l, int r, vector<int>& a) {
        if (l + 1 == r) {
            tree[v] = {a[l], l};
            return;
        }
        int m = (l + r) / 2;
        build(2 * v, l, m, a);
        build(2 * v + 1, m, r, a);
        tree[v] = min(tree[2 * v], tree[2 * v + 1]);
    }
    SegmentTree(vector<int>& a) {
        n = len(a);
        tree.resize(4 * n);
        push.assign(4 * n, 0);
        build(1, 0, n, a);
    }
    void modify(int v, int l, int r, int ql, int qr, int upd) {
        if (r <= ql || qr <= l) return;
        if (ql <= l && r <= qr) {
            receive_update(v, upd);
            return;
        }
        do_push(v);
        int m = (l + r) / 2;
        modify(2 * v, l, m, ql, qr, upd);
        modify(2 * v + 1, m, r, ql, qr, upd);
        tree[v] = min(tree[2 * v], tree[2 * v + 1]);
    }
    void modify(int ql, int qr, int upd) {
        modify(1, 0, n, ql, qr, upd);
    }
    pair<int, int> get(int v, int l, int r, int ql, int qr) {
        if (r <= ql || qr <= l) {
            return NEUTRAL;
        }
        if (ql <= l && r <= qr) {
            return tree[v];
        }
        do_push(v);
        int m = (l + r) / 2;
        return min(get(2 * v, l, m, ql, qr), get(2 * v + 1, m, r, ql, qr));
    }
    pair<int, int> get(int ql, int qr) {
        return get(1, 0, n, ql, qr);
    }
};
int n, k;
vector<int> r;
vector<int> val;
void init(i32 K, vector<i32> R) {
    n = len(R);
    r.resize(n);
    for (int i = 0; i < n; i++) {
        r[i] - R[i];
    }
    k = K;
    val.resize(n);
    SegmentTree tree(r);
    set<int> zero;
    set<pair<int, int>> q;
    auto add = [&] (int i) {
        auto it = zero.insert(i).first;
        auto it1 = it, it2 = it;
        if (it != zero.begin()) {
            it1--;
        }
        else {
            it1 = prev(zero.end());
        }
        it2++;
        if (it2 == zero.end()) {
            it2 = zero.begin();
        }
        int i1 = *it1, i2 = *it2;
        if (len(zero) > 1) {
            int dist = i2 - i1;
            if (dist <= 0) {
                dist += n;
            }
//            assert(q.count({dist, *it2}) == 1);
            q.erase({dist, i2});
        }
        int dist = i - i1;
        if (dist <= 0) dist += n;
        q.insert({dist, i});
        if (len(zero) > 1) {
            dist = i2 - i;
            if (dist <= 0) dist += n;
            q.insert({dist, i2});
        }
    };
    auto ers = [&] (int i) {
//        assert(zero.count(i) == 1);
        auto it = zero.find(i);
        auto it1 = it, it2 = it;
        if (it != zero.begin()) {
            it1--;
        }
        else {
            it1 = prev(zero.end());
        }
        it2++;
        if (it2 == zero.end()) {
            it2 = zero.begin();
        }
        int i1 = *it1, i2 = *it2;
        int dist = i - i1;
        if (dist <= 0) dist += n;
//        assert(q.count({dist, i}) == 1);
        q.erase({dist, i});
        if (len(zero) > 1) {
            dist = i2 - i;
            if (dist <= 0) dist += n;
//            assert(q.count({dist, *it2}) == 1);
            q.erase({dist, i2});
        }
        if (len(zero) > 1) {
            int dist = i2 - i1;
            if (dist <= 0) {
                dist += n;
            }
            q.insert({dist, i2});
        }
        zero.erase(it);
    };
    for (int cur = n - 1; cur >= 0; cur--) {
        while (true) {
            auto res = tree.get(0, n);
            if (res.first == 0) {
                add(res.second);
                tree.modify(res.second, res.second + 1, 2 * n);
            }
            else {
                break;
            }
        }
        vector<int> idx(all(zero));
//        assert(!q.empty());
        int mx = prev(q.end())->second;
        val[mx] = cur;
        ers(mx);
        tree.modify(max(0ll, mx - k + 1), mx, -1);
        tree.modify(min(n, n + mx - k + 1), n, -1);
    }
//    for (int i = 0; i < n; i++) {
//        cout << val[i] << ' ';
//    }
//    cout << '\n';
}
int compare_plants(int x, int y) {
    if (val[x] < val[y]) return -1;
	return 1;
}
