제출 #54579

#제출 시각아이디문제언어결과실행 시간메모리
54579aomeShortcut (IOI16_shortcut)C++17
97 / 100
2063 ms75004 KiB
#include "shortcut.h"

#include <bits/stdc++.h>

using namespace std;

const int N = 1000005;
const long long INF = 2e15;

int n, c;
int b[N];
int mn[N][2], mx[N][2];
bool visit[N];
long long a[N];
pair<long long, int> vec1[N], vec2[N];

bool check(long long dis) {
	long long mn1, mx1, mn2, mx2;
	mn1 = mn2 = -INF, mx1 = mx2 = INF;
	int ptr = 0;
	int opt[2][2];
	memset(opt, -1, sizeof opt);
	for (int i = 0; i < n; ++i) {
		while (ptr < n && vec1[i].first - vec2[ptr].first > dis) {
			int id = vec2[ptr].second;
			if (opt[0][0] == -1 || a[opt[0][0]] + b[opt[0][0]] < a[id] + b[id]) {
				opt[0][1] = opt[0][0], opt[0][0] = id;
			}
			else if (opt[0][1] == -1 || a[opt[0][1]] + b[opt[0][1]] < a[id] + b[id]) {
				opt[0][1] = id;
			}
			if (opt[1][0] == -1 || b[opt[1][0]] - a[opt[1][0]] < b[id] - a[id]) {
				opt[1][1] = opt[1][0], opt[1][0] = id;
			}
			else if (opt[1][1] == -1 || b[opt[1][1]] - a[opt[1][1]] < b[id] - a[id]) {
				opt[1][1] = id;
			}
			ptr++;
		}
		int id = vec1[i].second;
		int p0 = opt[0][0] == id ? opt[0][1] : opt[0][0];
		int p1 = opt[1][0] == id ? opt[1][1] : opt[1][0];
		if (p0 != -1) {
			mn1 = max(mn1, -(dis - c) + (a[id] + b[id]) + (a[p0] + b[p0]));
			mx2 = min(mx2, (dis - c) + (a[id] - b[id]) - (a[p0] + b[p0]));
		}
		if (p1 != -1) {
			mn2 = max(mn2, -(dis - c) + (a[id] + b[id]) + (b[p1] - a[p1]));
			mx1 = min(mx1, (dis - c) + (a[id] - b[id]) - (b[p1] - a[p1]));
		}
	}
	// cout << mn1 << ' ' << mx1 << ' ' << mn2 << ' ' << mx2 << '\n';
	ptr = -1;
	for (int i = n - 1; i >= 0; --i) {
		while (ptr + 1 < n && a[ptr + 1] <= mx1 - a[i]) ptr++;
		mx[i][0] = ptr;
	}
	ptr = -1;
	for (int i = 0; i < n; ++i) {
		while (ptr + 1 < n && a[ptr + 1] <= a[i] - mn2) ptr++;
		mx[i][1] = ptr;
	}
	ptr = n;
	for (int i = 0; i < n; ++i) {
		while (ptr - 1 >= 0 && a[ptr - 1] >= mn1 - a[i]) ptr--;
		mn[i][0] = ptr;
	}
	ptr = n;
	for (int i = n - 1; i >= 0; --i) {
		while (ptr - 1 >= 0 && a[ptr - 1] >= a[i] - mx2) ptr--;
		mn[i][1] = ptr;
	}
	for (int i = 0; i < n; ++i) {
		if (max(mn[i][0], mn[i][1]) <= min(mx[i][0], mx[i][1])) return 1;
	}
	return 0;
}

long long find_shortcut(int _n, vector<int> l, vector<int> d, int _c) {
	n = _n, c = _c;
	for (int i = 1; i < n; ++i) {
		a[i] = a[i - 1] + l[i - 1];
	}
	for (int i = 0; i < n; ++i) b[i] = d[i];
	for (int i = 0; i < n; ++i) {
		vec1[i] = {a[i] + b[i], i};
		vec2[i] = {a[i] - b[i], i};
	}
	sort(vec1, vec1 + n);
	sort(vec2, vec2 + n);
	long long low = 0, high = INF;
	while (low < high) {
		long long mid = (low + high) >> 1;
		if (check(mid)) high = mid; else low = mid + 1;
	}
	return low;
}
#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...