Submission #210099

# Submission time Handle Problem Language Result Execution time Memory
210099 2020-03-16T14:31:50 Z oolimry Shortcut (IOI16_shortcut) C++14
0 / 100
5 ms 380 KB
#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 = -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++;
		}
		
		///... 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(3) << "\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 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 5 ms 380 KB Secret is incorrect!
2 Halted 0 ms 0 KB -