제출 #210125

#제출 시각아이디문제언어결과실행 시간메모리
210125oolimryShortcut (IOI16_shortcut)C++14
97 / 100
2043 ms76592 KiB
#include "shortcut.h" #include <bits/stdc++.h> #define x first #define d second using namespace std; typedef pair<long long, long long> ii; long long inf = (1LL << 62LL); int n, C; ///ii(x, d) x - distance on main line, d is distance to side station static long long X[1000005]; ///sorted by increasing x static ii arr[1000005]; ///sorted by increasing x + d static ii arr2[1000005]; ///sorted by increasing x - d ///Vefify if it is possible to achieve diameter k ///For any pair of stations i and j (i < j), if x[j] - x[i] + d[i] + d[j], then it's fine ///Else let y and z be the positions of the shortcut edge ///d[i] + d[j] + |x[i] - y| + |x[i] - z| + C <= k must hold true ///Hence, the following conditions must be met: ///y + z >= (x[i] + d[i]) + (x[j] + d[j]) + C - k ... Let RHS = P ///y - z >= (x[i] + d[i]) - (x[j] - d[j]) + C - k ... Let RHS = Q ///y - z <= (x[i] - d[i]) - (x[j] + d[j]) - C + k ... Let RHS = R ///y + z <= (x[i] - d[i]) + (x[j] - d[j]) - C + k ... Let RHS = S bool check(long long k){ long long P = -inf, Q = -inf, R = inf, S = inf; ///maximise P & Q, minimise R & S. int i = 0; ///Basically, why need to store max and 2nd max is i != j (.-. so much work for that) long long maxXplusD = -inf, minXminusD = inf; ///the possible values from arr2 long long maxXPlusDPos = -1, minXminusDPos = -1; ///position of the above value long long max2XplusD = -inf, min2XminusD = inf; ///2nd max and 2nd min in case i == j for(int j = 0;j < n;j++){ ii J = arr[j]; while(i < n){ ii I = arr2[i]; if((J.x + J.d) - (I.x - I.d) <= k) break; if(I.x + I.d > maxXplusD){ max2XplusD = maxXplusD; maxXplusD = I.x + I.d; maxXPlusDPos = I.x; } else if(I.x + I.d > max2XplusD) max2XplusD = I.x + I.d; if(I.x - I.d < minXminusD){ min2XminusD = minXminusD; minXminusD = I.x - I.d; minXminusDPos = I.x; } else if(I.x - I.d < min2XminusD) min2XminusD = I.x - I.d; i++; } //cout << i << "\n"; ///... So annoying if(J.x == maxXPlusDPos) P = max(P, max2XplusD + (J.x + J.d)); else P = max(P, maxXplusD + (J.x + J.d)); if(J.x == maxXPlusDPos) Q = max(Q, max2XplusD - (J.x - J.d)); else Q = max(Q, maxXplusD - (J.x - J.d)); if(J.x == minXminusDPos) R = min(R, min2XminusD - (J.x + J.d)); else R = min(R, minXminusD - (J.x + J.d)); if(J.x == minXminusDPos) S = min(S, min2XminusD + (J.x - J.d)); else S = min(S, minXminusD + (J.x - J.d)); } if(i == 0) return true; ///Diameter <= k even with no shortcut //cout << P << " " << Q << " " << R << " " << S << "\n"; P += (C - k); Q += (C - k); R += (k - C); S += (k - C); //cout << P << " " << Q << " " << R << " " << S << "\n"; ///If we fix z, then max(P-z,Q+z) <= y <= min(R+z,S-z) ///[Note, in the code, z refers to index not value] for(int z = 1;z < n;z++){ long long lower = max(P - X[z], Q + X[z]); long long upper = min(R + X[z], S - X[z]); //cout << lower << " " << upper << "\n"; ///check if there exist a y between lower and upper if(upper_bound(X, X + z, upper) - lower_bound(X, X + z, lower) > 0) return true; } return false; } bool comp(ii a, ii b) { return a.x + a.d < b.x + b.d; } bool comp2(ii a, ii b) { return a.x - a.d < b.x - b.d; } long long find_shortcut(int _n, vector<int> l, vector<int> d, int _C){ n = _n, C = _C; arr[0].x = 0; arr[0].d = d[0]; for(int i = 1;i < n;i++){ arr[i] = ii(arr[i-1].x + l[i-1], d[i]); } for(int i = 0;i < n;i++){ X[i] = arr[i].x; arr2[i] = arr[i]; } sort(arr,arr+n,comp); sort(arr2,arr2+n,comp2); /* cout << check(4000000000) << "\n"; return 0; //*/ long long low = 0, high = inf; while(true){ if(low == high - 1) break; long long s = (low + high) / 2; if(check(s)) high = s; else low = s; } return high; }
#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...