#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 = 0, Q = 0, 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 = 0, minXminusD = inf; ///the possible values from arr2
long long maxXPlusDPos = -1, minXminusDPos = -1; ///position of the above value
long long max2XplusD = 0, 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++;
}
///... 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 P = 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) R = min(R, min2XminusD + (J.x - J.d));
else R = min(R, 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(51) << "\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 time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
376 KB |
n = 4, 80 is a correct answer |
2 |
Incorrect |
5 ms |
376 KB |
n = 9, incorrect answer: jury 110 vs contestant 100 |
3 |
Halted |
0 ms |
0 KB |
- |