Submission #132321

# Submission time Handle Problem Language Result Execution time Memory
132321 2019-07-18T17:18:51 Z hugo_pm Shortcut (IOI16_shortcut) C++17
0 / 100
2 ms 376 KB
#include "shortcut.h"
#include <cassert>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <vector>
using namespace std;
using llg = long long;
using pii = pair<llg, llg>;
 
const llg BIG = (llg)(1e9) * (llg)(1e7);
 
llg nbSta;
llg lenShortcut;
llg lenMap;
 
inline pii finAutor(llg tempsVise, llg debutShort, vector<llg> &pos, vector<llg> &poids, const vector<vector<llg>> &table, llg &maxAvant)
{
	pii finPos {0, BIG};
 
	int dd = max(0LL, debutShort-1);
	if (maxAvant == -134029) dd = 0;

	for (llg sta = dd; sta < debutShort; ++sta) {
		maxAvant = max(maxAvant, poids[sta] - pos[sta]);
		int dm = poids[sta] + pos[sta] + maxAvant;
		if (dm > tempsVise) return {-1, -1};
	}
 
	llg posDebut = pos[debutShort];
 
	for (llg sta = debutShort; sta < nbSta; ++sta) {
		llg risqueApres = table[sta][debutShort] - posDebut;
 
		bool canAvant = (poids[sta] + pos[sta] + maxAvant <= tempsVise);
		llg risqueAvant = posDebut + maxAvant;
		if (canAvant) risqueAvant = -BIG;
 
		if (canAvant && risqueApres < 0) continue;
 
		llg tempsPlus = tempsVise - max(risqueApres, risqueAvant) - lenShortcut - poids[sta];
		if (tempsPlus < 0) return {-1, -1};
		finPos.first = max(finPos.first, pos[sta] - tempsPlus);
		finPos.second = min(finPos.second, pos[sta] + tempsPlus);
	}
 
	return finPos;
}
 
vector<vector<llg>> t1, t2;
 
void genTable(vector<vector<llg>> &table, llg tempsVise, vector<llg> &pos, vector<llg> &poids)
{
	for (llg sta = 0; sta < nbSta; ++sta) {
		table[sta].resize(sta+1);
		table[sta][sta] = -BIG;
		llg maxAutor = tempsVise - poids[sta] - pos[sta];
		llg curMax = -BIG;
		for (llg prev = sta-1; prev >= 0; --prev) {
			llg valPrev = poids[prev] - pos[prev];
			if (valPrev > maxAutor) { // Ne peut pas etre attellg direct
				curMax = max(curMax, poids[prev] + pos[prev]);
			}
			table[sta][prev] = curMax;
		}
	}
}
 
bool estPossibleGlob(llg tempsVise, vector<llg> &pos, vector<llg> &revPos, vector<llg> &poids, vector<llg> &revPoids)
{
	vector<pii> finToDebut(nbSta);
	vector<bool> vu(nbSta, false);
	genTable(t1, tempsVise, revPos, revPoids);
 
	llg maxAvant = -BIG;
	auto gen = [&] (int sta) {
		llg o = -134029;
		pii x = finAutor(tempsVise, nbSta-1-sta, revPos, revPoids, t1, o);
		finToDebut[sta] = {lenMap - x.second, lenMap - x.first};
	};

	genTable(t2, tempsVise, pos, poids);
	for (llg deb = 0; deb < nbSta; ++deb) {
		pii posFinOk = finAutor(tempsVise, deb, pos, poids, t2, maxAvant);
		if (posFinOk.first == -1) continue;
		auto it = lower_bound(pos.begin(), pos.end(), posFinOk.first);
		int x = max((llg)(it - pos.begin()), deb);
		for (llg fin = x; fin < nbSta; ++fin) {
			if (pos[fin] > posFinOk.second) break;
			if (posFinOk.first <= pos[fin] && pos[fin] <= posFinOk.second) {
				if (! vu[fin]) {
					gen(fin);
					vu[fin] = true;
				}
				auto corDebOk = finToDebut[fin];
				if (corDebOk.first <= pos[deb] && pos[deb] <= corDebOk.second) {
					return true;
				}
			}
		}
	}
 
	return false;
}
 
long long find_shortcut(int _n, std::vector<int> _l, std::vector<int> _d, int _c)
{
	nbSta = _n;
	lenShortcut = _c;
	vector<llg> pos, revPos;
	vector<llg> poids, revPoids;
	pos.resize(nbSta);
	revPos.resize(nbSta);
	poids.resize(nbSta);
	revPoids.resize(nbSta);
	llg curPos = 0;
 
	t1.resize(nbSta);
	t2.resize(nbSta);
	for (llg iSta = 0; iSta < nbSta; ++iSta) {
		t1[iSta].resize(iSta+1);
		t2[iSta].resize(iSta+1);
		pos[iSta] = curPos;
		if (iSta < nbSta-1) curPos += _l[iSta];
 
		poids[iSta] = _d[iSta];
		revPoids[iSta] = _d[nbSta-1-iSta];
	}
 
	lenMap = pos.back();
 
	curPos = 0;
	for (llg iSta = nbSta-1; iSta >= 0; --iSta) {
		revPos[iSta] = curPos;
		if (iSta > 0) curPos += _l[iSta-1];
	}
 
	reverse(revPos.begin(), revPos.end());
	//reverse(revPoids.begin(), revPoids.end());
 
 
	llg lo = 0, ri = 0;
 
	pii toPr = {-1, -1};
 
	for (int a = 0; a < nbSta; ++a) {
		for (int b = a+1; b < nbSta; ++b) {
			lo = max(lo, poids[a] + poids[b] + min(lenShortcut, pos[b] - pos[a]));
			llg newRi = max(ri, poids[a] + poids[b] + (pos[b] - pos[a]));
			if (newRi > ri) {
				newRi = ri;
				toPr = {a, b};
			}
		}
	}
 
	auto gd = [&] (int a, int b) {
		llg r1 = abs(pos[a] - pos[b]);
		llg r2 = abs(pos[a] - pos[toPr.first]) + lenShortcut + abs(pos[b] - pos[toPr.second]);
		llg r3 = abs(pos[a] - pos[toPr.second]) + lenShortcut + abs(pos[b] - pos[toPr.first]);
		return min(r1, min(r2, r3));
	};
 
	ri = 0;
 
	for (int a = 0; a < nbSta; ++a) {
		for (int b = a+1; b < nbSta; ++b) {
			ri = max(ri, poids[a] + poids[b] + gd(a, b));
		}
	}
 
	cout << lo << " " << ri << "\n";
	while (lo < ri) {
		llg mid = (lo + ri) / 2;
		if (ri-lo > 100) mid -= 7;
		if (estPossibleGlob(mid, pos, revPos, poids, revPoids)) {
			ri = mid;
		} else {
			lo = mid+1;
		}
	}
 
	return lo;
}
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 2 ms 376 KB Secret is incorrect!
2 Halted 0 ms 0 KB -