Submission #1054142

#TimeUsernameProblemLanguageResultExecution timeMemory
1054142Gromp15Comparing Plants (IOI20_plants)C++17
44 / 100
417 ms32552 KiB
#include <bits/stdc++.h> #define ll long long #include "plants.h" #define ar array #define all(x) x.begin(), x.end() #define sz(x) (int)x.size() using namespace std; const int INF = 1e9; struct seg { int N; vector<ar<int, 2>> tree; vector<int> lazy; void pull(int node) { tree[node] = min(tree[node*2], tree[node*2+1]); } void push(int node) { if (!lazy[node]) return; tree[node][0] += lazy[node]; if (node < N) lazy[node*2] += lazy[node], lazy[node*2+1] += lazy[node]; lazy[node] = 0; } seg(int n, const vector<int>& r) : N(1<<(__lg(n)+1)), tree(2*N), lazy(2*N) { for (int i = 0; i < n; i++) tree[i+N] = {r[i], i}; for (int i = N-1; i >= 1; i--) pull(i); } ar<int, 2> query(int node, int nl, int nr, int ql, int qr) { push(node); if (ql > nr || qr < nl) return {INF}; if (ql <= nl && nr <= qr) return tree[node]; int mid = (nl+nr)/2; return min(query(node*2, nl, mid, ql, qr), query(node*2+1, mid+1, nr, ql, qr)); } void update(int node, int nl, int nr, int ql, int qr, int v) { push(node); if (ql > nr || qr < nl) return; if (ql <= nl && nr <= qr) { lazy[node] += v; push(node); return; } int mid = (nl+nr)/2; update(node*2, nl, mid, ql, qr, v), update(node*2+1, mid+1, nr, ql, qr, v); pull(node); } }; int n, k; vector<int> got; vector<int> r; void init(int _k, std::vector<int> _r) { k = _k; r = _r; n = sz(r); seg st(n, r); got.resize(n); set<int> in; set<ar<int, 2>> where; auto dist = [&](int x) { return x < 0 ? x + n : x; }; auto add = [&](int pos) { //cout << "Add " << pos << endl; assert(!in.count(pos)); if (in.size() > 1) { auto it = in.lower_bound(pos); int R = it != in.end() ? *it : *in.begin(); int L = it != in.begin() ? *prev(it) : *prev(in.end()); assert(where.count({dist(R - L), R})); where.erase({dist(R - L), R}); where.insert({dist(R - pos), R}); where.insert({dist(pos - L), pos}); } else if (in.size() == 1) { int other = *in.begin(); assert(where.size() == 1); assert((*where.begin())[0] == n); where.erase(where.begin()); where.insert({dist(other - pos), other}); where.insert({dist(pos - other), pos}); } else { where.insert({n, pos}); } in.insert(pos); }; auto rem = [&](int pos) { //cout << "Rem " << pos << endl; assert(in.count(pos)); if (in.size() == 1) { in.erase(in.begin()); where.erase(where.begin()); } else if (in.size() == 2) { int other = *in.begin() == pos ? *next(in.begin()) : *in.begin(); assert(where.count({dist(pos - other), pos})); in.erase(pos); where.erase(where.begin()); where.erase(where.begin()); where.insert({n, other}); } else { auto it = in.upper_bound(pos); int R = it != in.end() ? *it : *in.begin(); auto it2 = in.lower_bound(pos); int L = it2 != in.begin() ? *prev(it2) : *prev(in.end()); assert(where.count({dist(R - pos), R})); assert(where.count({dist(pos - L), pos})); where.erase({dist(R - pos), R}); where.erase({dist(pos - L), pos}); where.insert({dist(R - L), R}); in.erase(pos); } }; int on = n; while (1) { /* cout << "Cur\n"; for (int i = 0; i < n; i++) cout << st.query(1, 0, st.N-1, i, i)[0] << " \n"[i==n-1]; cout.flush(); */ auto q = st.query(1, 0, st.N-1, 0, n-1); if (!q[0]) { add(q[1]); st.update(1, 0, st.N-1, q[1], q[1], INF); } else { if (where.empty()) break; auto [val, pos] = *prev(where.end()); assert(val >= k); rem(pos); got[pos] = on--; int L = pos - k + 1, R = pos - 1; if (L < 0) L += n; if (R < 0) R += n; if (L <= R) st.update(1, 0, st.N-1, L, R, -1); else { st.update(1, 0, st.N-1, 0, R, -1); st.update(1, 0, st.N-1, L, n-1, -1); } } } } bool win(int x, int y) { return got[x] > got[y]; } int compare_plants(int x, int y) { int w1 = win(x, y), w2 = win(y, x); assert(w1 || w2); return w1 && w2 ? 0 : w1 ? 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...