Submission #1043931

#TimeUsernameProblemLanguageResultExecution timeMemory
1043931HydrolyzedHoliday (IOI14_holiday)C++17
0 / 100
60 ms65536 KiB
#include <bits/stdc++.h> #include"holiday.h" using namespace std; using ll = long long; const int MxN = 100010; struct node_t; using pnode_t = node_t *; struct node_t { ll v; int cnt; pnode_t l, r; node_t(ll _v=0ll, int _cnt=0): v(_v), cnt(_cnt), l(nullptr), r(nullptr) {} friend node_t operator + (const node_t &lhs, const node_t &rhs) { return node_t(lhs.v + rhs.v, lhs.cnt + rhs.cnt); } }; struct interval_t { ll v; int l, r; interval_t(ll _v): v(_v), l(0), r(0) {} }; int n, stp, days; ll a[MxN]; pnode_t roots[MxN]; namespace persistent { void build(int l, int r, pnode_t &cur) { cur = new node_t(); if(l == r) { cur->v = 0ll; cur->cnt = 0ll; return ; } int mid = (l + r) >> 1; build(l, mid, cur->l); build(mid + 1, r, cur->r); cur->v = cur->l->v + cur->r->v; cur->cnt = cur->l->cnt + cur->r->cnt; } void update(int l, int r, int id, node_t val, pnode_t &cur, pnode_t pre) { cur = new node_t(*pre); #ifdef ICY cerr << "UPDATING: " << l << " " << r << "\n"; #endif if(l == r) { cur->v = val.v; cur->cnt = 1; return ; } int mid = (l + r) >> 1; if(id <= mid) { update(l, mid, id, val, cur->l, pre->l); } else { update(mid + 1, r, id, val, cur->r, pre->r); } #ifdef ICY cerr << "RANGE: [" << l << ", " << r << "]\n"; cerr << "AFTER UPDATED: L(" << (cur->l == nullptr ? "NULL" : "HAVE!") << "), R(" << (cur->r == nullptr ? "NULL" : "HAVE!") << ")\n"; #endif cur->v = cur->l->v + cur->r->v; cur->cnt = cur->l->cnt + cur->r->cnt; } ll calc(int l, int r, pnode_t old_ver, pnode_t new_ver, ll x) { #ifdef ICY assert(old_ver != nullptr && "old_ver is null"); assert(new_ver != nullptr && "new_ver is null"); cerr << "IN PERSIST: " << l << " " << r << "\n"; #endif if(l > r) { return 0ll; } if(l == r) { if(x <= 0ll) { return 0ll; } if(new_ver->cnt - old_ver->cnt <= x) { return new_ver->v - old_ver->v; } } #ifdef ICY cerr << "GOING SOMEWHERE" << "\n"; assert(old_ver->r != nullptr && "old_ver is null"); assert(new_ver->r != nullptr && "new_ver is null"); #endif int mid = (l + r) >> 1; ll right_count = new_ver->r->cnt - old_ver->r->cnt; #ifdef ICY cerr << "RIGHT COUNT: " << right_count << "\n"; #endif if(right_count >= x) { #ifdef ICY cerr << "GO LEFT\n"; #endif return calc(l, mid, old_ver->l, new_ver->l, x); } #ifdef ICY cerr << "GO RIGHT\n"; #endif return new_ver->r->v - old_ver->r->v + calc(mid + 1, r, old_ver->r, new_ver->r, x - right_count); } } ll divide(int l, int r, int opt_l, int opt_r) { if(l > r) { return 0ll; } int mid = (l + r) >> 1; ll res = 0ll; interval_t best(0ll); for(int k=opt_l; k<=opt_r; ++k) { int needs = mid - k + min(stp - k, mid - stp); if(needs > days) { continue; } #ifdef ICY cerr << "ASKING: " << days - needs + 1 << " " << k << "[" << n << "]\n"; #endif ll cur_answer = persistent::calc(1, n, roots[k], roots[mid], days - needs + 1); #ifdef ICY cerr << "DONE QUERY: " << cur_answer << "\n"; #endif if(best.v < cur_answer) { best.v = cur_answer; best.l = best.r = k; } else if(best.v == cur_answer) { best.r = k; } } res = max(res, divide(l, mid - 1, opt_l, best.r)); res = max(res, divide(mid + 1, r, best.l, opt_r)); return res; } long long findMaxAttraction(int n, int start, int d, int attraction[]) { stp = start + 1; days = d; ::n = n; vector<pair<ll, int>> c_a; for(int i=1; i<=n; ++i) { a[i] = (ll) attraction[i - 1]; c_a.emplace_back(a[i], i); } sort(c_a.begin(), c_a.end()); persistent::build(1, n, roots[0]); for(int i=1; i<=n; ++i) { int idx = upper_bound(c_a.begin(), c_a.end(), make_pair(a[i - 1], i)) - c_a.begin(); persistent::update(1, n, idx, node_t(c_a[idx - 1].first, 1), roots[i], roots[i - 1]); #ifdef ICY cerr << "ROOT(" << i << "): " << (roots[i] != nullptr ? "": "MISSING") << "\n"; #endif } #ifdef ICY cerr << "DONE BUILDING!\n"; #endif ll answer = divide(start, n, 1, start - 1); return answer; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...