Submission #140828

#TimeUsernameProblemLanguageResultExecution timeMemory
140828NamnamseoShortcut (IOI16_shortcut)C++17
0 / 100
2 ms504 KiB
#include "shortcut.h" #include <bits/stdc++.h> using namespace std; using ll=long long; using pll=pair<ll,ll>; #define all(x) x.begin(), x.end() #define x first #define y second const int maxn = int(1e6) + 10; int n; int C; ll pos[maxn]; ll d[maxn]; pll rpdr[maxn]; pll lmdl[maxn]; const ll inf = 1ll<<60; struct BoundSys { pll mx, smx; void init(){ mx = smx = {-inf, -1}; } BoundSys(){ init(); } void upd(ll val, ll idx) { pll t(val, idx); if(mx < t) smx = mx, mx = t; else if(smx < t) smx = t; } ll get_max(ll idx) { if(mx.y != -1 && mx.y != idx) return mx.x; else if(smx.y != -1) return smx.x; else return -inf; } }; struct Gug { BoundSys bl, br; ll rL, rR; Gug(){ bl.init(); br.init(); rL = -inf; rR = +inf; } void Add(ll lv, ll rv, ll i) { bl.upd(lv, i); br.upd(-rv, i); } void upd(ll lv, ll rv, ll i) { rL = max(rL, bl.get_max(i) + lv); rR = min(rR, -br.get_max(i) + rv); } }; bool f(ll X) { int lst = n; Gug ipj, imj; auto Add = [&](int r) { //printf("Add R=%d\n", r); ipj.Add(pos[r] + d[r], pos[r]-d[r], r); imj.Add(d[r] - pos[r], d[r]+pos[r], r); }; auto Upd = [&](int l) { //printf("Upd L=%d\n", l); ipj.upd(pos[l] + d[l] + C-X, pos[l] - d[l] + X-C, l); imj.upd(pos[l] + d[l] + C-X, pos[l] - d[l] + X-C, l); //printf("i+j updated to %lld %lld (%lld,%lld / %lld,%lld)\n", ipj.rL, ipj.rR, ipj.bl.mx.y, ipj.bl.smx.y, ipj.br.mx.y, ipj.br.smx.y); }; for(int i=n-1; 0<=i; --i) { while(lst-1 >= 0 && rpdr[lst-1].x > lmdl[i].x + X) { --lst; Add(rpdr[lst].y); } Upd(lmdl[i].y); } int j = 0; for(int i=0; i<n; ++i) { int pi = pos[i]; ll jmin = max(ipj.rL - pi, pi - imj.rR); ll jmax = min(ipj.rR - pi, pi - imj.rL); while(j+1 < n && pos[j] < jmin) ++j; while(0 <= j-1 && pos[j] > jmax) --j; if(jmin <= pos[j] && pos[j] <= jmax) { return 1; } } return 0; } long long find_shortcut(int _n, std::vector<int> l, std::vector<int> _d, int c) { n = _n; C = c; copy(all(_d), d); partial_sum(all(l), pos+1); for(int i=0; i<n; ++i) { rpdr[i] = {pos[i] + d[i], i}; lmdl[i] = {pos[i] - d[i], i}; } sort(rpdr, rpdr+n); sort(lmdl, lmdl+n); ll L = 0, R = (1ll<<60); ll pmx = 0; for(int i=0; i<n; ++i) { if(i) L = max(L, d[i] + pmx); pmx = max(pmx, d[i]); } //printf("Call range %lld-%lld\n", L, R); //f(110); //return 0; while(L+1 < R) { ll mid = (L+R) / 2; if(f(mid)) R = mid; else L = mid; } return R; }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...