Submission #405404

#TimeUsernameProblemLanguageResultExecution timeMemory
405404tiberiuComparing Plants (IOI20_plants)C++14
25 / 100
4070 ms19764 KiB
#include "plants.h" #include <iostream> using namespace std; const int MAX_N = 2e5; int N, K; int v[MAX_N], hGen[MAX_N]; int aint_mn[4 * MAX_N]; int aint_pos[4 * MAX_N]; int aint_lazy[4 * MAX_N]; int cval; void propag(int n, int nl, int nr) { aint_mn[n * 2 + 1] += aint_lazy[n]; aint_lazy[n * 2 + 1] += aint_lazy[n]; aint_mn[n * 2 + 2] += aint_lazy[n]; aint_lazy[n * 2 + 2] += aint_lazy[n]; aint_lazy[n] = 0; } void init_aint(int n = 0, int nl = 0, int nr = 0) { if (n == 0) nr = N - 1; aint_pos[n] = nl; if (nl < nr) { int mid = (nl + nr) / 2; init_aint(n * 2 + 1, nl, mid); init_aint(n * 2 + 2, mid + 1, nr); } } pair<int, int> query(int l, int r, int n = 0, int nl = 0, int nr = 0) { if (n == 0) nr = N - 1; if (l == nl && r == nr) { return {aint_mn[n], aint_pos[n]}; } propag(n, nl, nr); pair<int, int> q1, q2; int mid = (nl + nr) / 2; if (r <= mid) return query(l, r, n * 2 + 1, nl, mid); else if (l > mid) return query(l, r, n * 2 + 2, mid + 1, nr); else { q1 = query(l, mid, n * 2 + 1, nl, mid); q2 = query(mid + 1, r, n * 2 + 2, mid + 1, nr); return min(q1, q2); } } void update(int l, int r, int val, int n = 0, int nl = 0, int nr = 0) { if (n == 0) nr = N - 1; if (l == nl && r == nr) { aint_mn[n] += val; aint_lazy[n] += val; return; } propag(n, nl, nr); int mid = (nl + nr) / 2; if (l <= mid) update(l, min(mid, r), val, n * 2 + 1, nl, mid); if (r > mid) update(max(mid + 1, l), r, val, n * 2 + 2, mid + 1, nr); if (aint_mn[n * 2 + 1] < aint_mn[n * 2 + 2]) { aint_mn[n] = aint_mn[n * 2 + 1]; aint_pos[n] = aint_pos[n * 2 + 1]; } else { aint_mn[n] = aint_mn[n * 2 + 2]; aint_pos[n] = aint_pos[n * 2 + 2]; } } void solve(int x) { if (x >= K - 1) { pair<int, int> q = query(x - K + 1, x - 1); if (q.first == 0) { solve(q.second); solve(x); return; } } else { pair<int, int> q = query(N + x - K + 1, N - 1); if (q.first != 0 && x > 0) q = query(0, x - 1); if (q.first == 0) { solve(q.second); solve(x); return; } } hGen[x] = cval; cval--; if (x >= K - 1) { update(x - K + 1, x - 1, -1); } else { if (x > 0) update(0, x - 1, -1); update(N + x - K + 1, N - 1, -1); } update(x, x, +1000000); } void gen(int k, vector<int> r) { init_aint(); for (int i = 0; i < N; i++) { update(i, i, r[i]); } cval = N; while (aint_mn[0] == 0) { solve(aint_pos[0]); } } int leftV[MAX_N]; int rightV[MAX_N]; #include <set> void calc_lr() { multiset<pair<int, int>> w; for (int i = N - K + 1; i < N; i++) { w.insert({hGen[i], i}); } for (int i = 0; i < N; i++) { multiset<pair<int, int>>::iterator it = w.lower_bound({hGen[i], i}); if (it != w.begin()) { it--; leftV[i] = it->second; } else leftV[i] = -1; int rmv = (N + i - K + 1) % N; w.erase({hGen[rmv], rmv}); w.insert({hGen[i], i}); } w.clear(); for (int i = 0; i < K - 1; i++) { w.insert({hGen[i], i}); } for (int i = N - 1; i >= 0; i--) { multiset<pair<int, int>>::iterator it = w.lower_bound({hGen[i], i}); if (it != w.begin()) { it--; rightV[i] = it->second; } else rightV[i] = -1; int rmv = (N + i + K - 1) % N; w.erase({hGen[rmv], rmv}); w.insert({hGen[i], i}); } } void init(int k, std::vector<int> r) { K = k; N = r.size(); gen(k, r); calc_lr(); return; } int compare_plants(int x0, int y0) { int x = x0, y = y0; while ((y - x + N) % N >= K && rightV[x] != -1) x = rightV[x]; if ((y - x + N) % N < K && hGen[x] > hGen[y]) return 1; x = x0; while ((y - x + N) % N >= K && leftV[y] != -1) y = leftV[y]; if ((y - x + N) % N < K && hGen[y] > hGen[x]) return -1; y = y0; while ((x - y + N) % N >= K && leftV[x] != -1) x = leftV[x]; if ((x - y + N) % N < K && hGen[x] > hGen[y]) return 1; x = x0; while ((x - y + N) % N >= K && rightV[y] != -1) y = rightV[y]; if ((x - y + N) % N < K && hGen[y] > hGen[x]) return -1; y = y0; return 0; }
#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...