Submission #436440

#TimeUsernameProblemLanguageResultExecution timeMemory
43644079brueShortcut (IOI16_shortcut)C++14
97 / 100
2021 ms72752 KiB
#include <bits/stdc++.h> #include "shortcut.h" using namespace std; typedef long long ll; ll minCost(vector<int> v){ sort(v.rbegin(), v.rend()); return v[0] + v[1]; } 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 = minCost(d), MAX = 1e18, ANS = 1e18; while(MIN <= MAX){ ll MID = (MIN + MAX) / 2; if(able(MID)){ ANS = MID; MAX = MID-1; } else MIN = MID+1; } return ANS; } 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]; while(pnt <= n && arr[vec[pnt]] + loc[vec[pnt]] > X + loc[x] - arr[x]){ ll tmp = loc[vec[pnt]] - arr[vec[pnt]]; if(minXmd2 > tmp){ minXmd2 = tmp; if(minXmd > minXmd2) swap(minXmd, minXmd2), minXmdLoc = vec[pnt]; } 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) continue; if(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...