Submission #837506

#TimeUsernameProblemLanguageResultExecution timeMemory
837506pavementComparing Plants (IOI20_plants)C++17
59 / 100
652 ms53500 KiB
#include "plants.h" #include <bits/stdc++.h> using namespace std; #define mp make_pair using ii = pair<int, int>; int n; vector<int> r, h[2]; struct node { node *left, *right; int S, E, pv; ii val; node(int _s, int _e) : S(_s), E(_e), pv(0) { if (S == E) { val = mp(r[S], S); return; } int M = (S + E) / 2; left = new node(S, M); right = new node(M + 1, E); val = min(left->val, right->val); } void prop() { if (S == E || !pv) { return; } left->val.first += pv; left->pv += pv; right->val.first += pv; right->pv += pv; pv = 0; } void upd(int l, int r, int v) { if (l > E || r < S) { return; } if (l <= S && E <= r) { val.first += v; pv += v; return; } prop(); left->upd(l, r, v); right->upd(l, r, v); val = min(left->val, right->val); } } *root; void init(int k, vector<int> r) { n = (int)r.size(); auto dist = [&](int i, int j) { int ret = j - i; if (ret < 0) { return ret + n; } else { return ret; } }; for (int rep = 0; rep < 2; rep++) { ::r = r; h[rep].resize(n); root = new node(0, n - 1); set<int> zeroes; set<ii> candidates; auto candidates_insert = [&](int a, int b) { if (a >= k) { candidates.emplace(b, a); } }; auto candidates_erase = [&](int a, int b) { if (a >= k) { candidates.erase(mp(b, a)); } }; for (int i = n - 1; i >= 0; i--) { while (root->val.first == 0) { int cur_pos = root->val.second; if (zeroes.empty()) { candidates_insert(n, cur_pos); } else if ((int)zeroes.size() == 1) { int x = *zeroes.begin(); candidates_erase(n, x); candidates_insert(dist(cur_pos, x), x); candidates_insert(dist(x, cur_pos), cur_pos); } else { auto it = zeroes.lower_bound(cur_pos); if (it == zeroes.end()) { it = zeroes.begin(); } int nxt = *it; if (it == zeroes.begin()) { it = zeroes.end(); } --it; int prv = *it; candidates_erase(dist(prv, nxt), nxt); candidates_insert(dist(prv, cur_pos), cur_pos); candidates_insert(dist(cur_pos, nxt), nxt); } zeroes.insert(cur_pos); root->upd(cur_pos, cur_pos, (int)1e9); } assert(!zeroes.empty()); auto [pos, len] = *candidates.rbegin(); zeroes.erase(pos); { candidates_erase(len, pos); if ((int)zeroes.size() == 1) { candidates_erase(dist(pos, *zeroes.begin()), *zeroes.begin()); candidates_insert(n, *zeroes.begin()); } else if ((int)zeroes.size() >= 2) { auto it = zeroes.lower_bound(pos); if (it == zeroes.end()) { it = zeroes.begin(); } int nxt = *it; if (it == zeroes.begin()) { it = zeroes.end(); } --it; int prv = *it; candidates_erase(dist(pos, nxt), nxt); candidates_insert(dist(prv, nxt), nxt); } } assert(pos != -1); h[rep][pos] = i; if (pos - k + 1 < 0) { root->upd(pos - k + 1 + n, n - 1, -1); root->upd(0, pos - 1, -1); } else { root->upd(pos - k + 1, pos - 1, -1); } } for (int &i : r) { i = k - 1 - i; } } } int compare_plants(int x, int y) { if ((h[0][x] < h[0][y]) != (h[1][x] > h[1][y])) { return 0; } else { return (h[0][x] < h[0][y] ? -1 : 1); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...