Submission #436455

#TimeUsernameProblemLanguageResultExecution timeMemory
43645579brueShortcut (IOI16_shortcut)C++14
97 / 100
2081 ms47252 KiB
#include <algorithm> #include <vector> #pragma GCC optimize("O3") #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #pragma GCC target("avx2") #include "shortcut.h" #define min(a, b) ((a)<(b)?(a):(b)) #define max(a, b) ((a)>(b)?(a):(b)) using namespace std; typedef long long ll; int n; ll cost; ll arr[1000002]; ll loc[1000002]; ll vec[1000002]; ll vec2[1000002]; ll maxXpd, maxXpd2; bool able(ll); ll find_shortcut(int N, vector<int> l, vector<int> d, int C){ n = N; for(int i=1; i<=n; i++) arr[i] = d[i-1]; for(int i=2; i<=n; i++) loc[i] = loc[i-1] + l[i-2]; cost = C; for(int i=1; i<=n; i++) vec[i] = vec2[i] = i; sort(vec+1, vec+n+1, [&](int a, int b){ return arr[a] + loc[a] > arr[b] + loc[b]; }); sort(vec2+1, vec2+n+1, [&](int a, int b){ return loc[a] - arr[a] > loc[b] - arr[b]; }); maxXpd = arr[vec[1]] + loc[vec[1]]; maxXpd2 = arr[vec[2]] + loc[vec[2]]; ll MIN = 0, MAX = 2e15, ANS = 2e15; while(MIN <= MAX){ ll MID = (MIN + MAX) / 2; if(able(MID)){ ANS = MID; MAX = MID-1; } else MIN = MID+1; } return ANS; } inline bool able(ll X){ ll minPlus = -1e18, maxPlus = 1e18; ll minMinus = -1e18, maxMinus = 1e18; int pnt = 1; ll minXmd = 1e18, minXmd2 = 1e18; int minXmdLoc = -1; for(int i=1; i<=n; i++){ int x = vec2[i]; int tv = vec[pnt]; while(pnt <= n && arr[tv] + loc[tv] > X + loc[x] - arr[x]){ ll tmp = loc[tv] - arr[tv]; if(minXmd2 > tmp){ minXmd2 = tmp; if(minXmd > minXmd2) swap(minXmd, minXmd2), minXmdLoc = tv; } tv = vec[++pnt]; } if(pnt==1 || (pnt==2 && x==vec[1]) || (pnt==2 && x==minXmdLoc)) continue; ll tMax = (x==vec[1] ? maxXpd2 : maxXpd); ll tMin = (x==minXmdLoc ? minXmd2 : minXmd); maxPlus = min(maxPlus, loc[x] - arr[x] + X + tMin - cost); minPlus = max(minPlus, loc[x] + arr[x] - X + tMax + cost); maxMinus = min(maxMinus, -loc[x] - arr[x] + X + tMin - cost); minMinus = max(minMinus, -loc[x] + arr[x] - X + tMax + cost); } int pL = n+1, pR = n; int mL = 1, mR = 0; for(int i=1; i<=n; i++){ while(pL > 1 && loc[pL-1] + loc[i] >= minPlus) pL--; while(pR && loc[pR] + loc[i] > maxPlus) pR--; while(mL < i-1 && loc[i] - loc[mL] > maxMinus) mL++; while(mR < i-1 && loc[i] - loc[mR+1] >= minMinus) mR++; if(pL > pR || mL > mR || pR < mL || mR < pL) continue; return true; } return false; }
#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...