Submission #1092941

#TimeUsernameProblemLanguageResultExecution timeMemory
1092941shivansh0809Holiday (IOI14_holiday)C++17
24 / 100
83 ms65536 KiB
#include "holiday.h" #include <bits/stdc++.h> using namespace std; struct PersistentSegTree { // find_kth returns the kth smallest element in the array in [l, r) struct Vertex { Vertex *l, *r; long long sum; long long k_sum; Vertex(long long val) : l(nullptr), r(nullptr), sum(val), k_sum(0) {} Vertex(long long val, long long k_sum) : l(nullptr), r(nullptr), sum(val), k_sum(k_sum) {} Vertex(Vertex *l, Vertex *r) : l(l), r(r), sum(0), k_sum(0) { if (l) sum += l->sum, k_sum += l->k_sum; if (r) sum += r->sum, k_sum += r->k_sum; } }; vector<Vertex *> roots; map<long long, pair<long long, long long>> compress; long long n; PersistentSegTree(vector<long long> v) : n(v.size()) { long long tl = 0, tr = n; vector<pair<long long, long long>> sort_v; for (long long i = 0; i < n; i++) sort_v.push_back({v[i], i}); sort(sort_v.begin(), sort_v.end(), greater<pair<long long, long long>>()); vector<long long> idx(n); for (long long i = 0; i < n; i++) compress[i] = sort_v[i], idx[sort_v[i].second] = i; roots.push_back(build(tl, tr)); for (long long i = 0; i < n; i++) roots.push_back(update(roots.back(), tl, tr, idx[i])); } Vertex *build(long long tl, long long tr) { if (tl == tr) return new Vertex(0LL, 0LL); long long tm = (tl + tr) / 2; return new Vertex(build(tl, tm), build(tm + 1, tr)); } Vertex *update(Vertex *v, long long tl, long long tr, long long pos) { if (tl == tr) return new Vertex(v->sum + 1, v->k_sum + compress[pos].first); long long tm = (tl + tr) / 2; if (pos <= tm) return new Vertex(update(v->l, tl, tm, pos), v->r); else return new Vertex(v->l, update(v->r, tm + 1, tr, pos)); } long long find_kth(Vertex *vl, Vertex *vr, long long tl, long long tr, long long k) { if (tl == tr) return vr->k_sum - vl->k_sum; long long tm = (tl + tr) / 2; long long left_count = vr->l->sum - vl->l->sum; if (left_count >= k) return find_kth(vl->l, vr->l, tl, tm, k); return vr->l->k_sum - vl->l->k_sum + find_kth(vl->r, vr->r, tm + 1, tr, k - left_count); } long long find_kth(long long l, long long r, long long k) { return find_kth(roots[l], roots[r], 0, n, k); } }; long long int findMaxAttraction(int n, int start, int d, int attraction[]) { long long ans = 0; PersistentSegTree pst(vector<long long>(attraction, attraction + n)); function<long long(long long, long long)> C1 = [&](long long k, long long mid) -> long long { long long days_rem = d - (mid - k + start - k); if (days_rem <= 0) return 0; return pst.find_kth(k, mid + 1, days_rem); // return mid - k; }; function<long long(long long, long long)> C2 = [&](long long mid, long long k) -> long long { long long days_rem = d - (k - mid + k - start); if (days_rem <= 0) return 0; return pst.find_kth(mid, k + 1, days_rem); // return k - mid; }; function<void(long long, long long, long long, long long)> dncg = [&](long long l, long long r, long long optl, long long optr) { if (l > r) return; long long mid = (l + r) >> 1; pair<long long, long long> best = {-1, -1}; for (long long k = optl; k <= min(mid, optr); k++) best = max(best, {C1(k, mid), k}); // debug(dp, best, ndp); // debug(ans, best, mid); ans = max(best.first, ans); long long opt = best.second; dncg(l, mid - 1, optl, opt); dncg(mid + 1, r, opt, optr); }; function<void(long long, long long, long long, long long)> dncs = [&](long long l, long long r, long long optl, long long optr) { if (l > r) return; long long mid = (l + r) >> 1; pair<long long, long long> best = {-1, -1}; for (long long k = optr; k >= max(mid, optl); k--) best = max(best, {C2(mid, k), k}); // debug(dp, best, ndp); // debug(ans, best, mid); ans = max(best.first, ans); long long opt = best.second; dncs(l, mid - 1, optl, opt); dncs(mid + 1, r, opt, optr); }; if (d == 0) return 0; ans = attraction[start]; dncg(start + 1, n - 1, 0, start); dncs(0, start - 1, start, n - 1); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...