Submission #1343278

#TimeUsernameProblemLanguageResultExecution timeMemory
1343278AMnuSky Walking (IOI19_walk)C++20
100 / 100
1822 ms167188 KiB
#include "walk.h"
#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef vector <int> arr;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;

const int MAXN = 1e5+5, MAXT = 18e5+5;
const ll INF = 1e18;

int N, M, S[2], T;
ll dist[MAXT];
arr Y, in[MAXN], out[MAXN];
map <int,int> ver[MAXN], hor[MAXN];
vector <pii> adj[MAXT];
set <pii> sky;
priority_queue <pli,vector<pli>,greater<pli> > PQ;

int get(int x,int y) {
	int &p = ver[x][y];
	if (!p) {
		T++;
		p = T;
	}
	return p;
}

int gethor(int id,int x) {
	int &p = hor[id][x];
	if (!p) {
		p = get(x,Y[id]);
	}
	return p;
}

ll min_distance(arr X,arr H,arr L,arr R,arr YY,int st,int fn) {
	Y = YY;
	N = X.size();
	M = Y.size();
	S[0] = st;
	S[1] = fn;
	get(st,0);
	get(fn,0);
	for (int i=0;i<M;i++) {
		in[L[i]].push_back(i);
		out[R[i]].push_back(i);
		gethor(i,L[i]);
		gethor(i,R[i]);
		for (int t=0;t<2;t++) {
			if (S[t] <= L[i] || S[t] >= R[i]) continue;
			for (int j=S[t];1;j--) {
				if (H[j] >= Y[i]) {
					gethor(i,j);
					break;
				}
			}
			for (int j=S[t];1;j++) {
				if (H[j] >= Y[i]) {
					gethor(i,j);
					break;
				}
			}
		}
	}
	for (int i=1;i<N-1;i++) {
		for (int x : in[i-1]) {
			sky.insert({Y[x],x});
		}
		for (int x : out[i]) {
			sky.erase({Y[x],x});
		}
		set <int> cand;
		for (auto x : ver[i]) {
			auto y = sky.lower_bound({x.fi+1,0});
			if (y != sky.end() && y->fi <= H[i]) {
				cand.insert(y->se);
			}
			if (y == sky.begin()) continue;
			y--;
			if (y->fi == x.fi) {
				if (y == sky.begin()) continue;
				y--;
			}
			cand.insert(y->se);
		}
		for (auto x : cand) {
			gethor(x,i);
		}
	}
	for (int i=0;i<M;i++) {
		pii last = {-1,-1};
		for (auto x : hor[i]) {
			if (last.fi != -1) {
				int d = X[x.fi]-X[last.fi];
				adj[x.se].push_back({last.se,d});
				adj[last.se].push_back({x.se,d});
			}
			last = x;
		}
	}
	for (int i=0;i<N;i++) {
		pii last = {-1,-1};
		for (auto x : ver[i]) {
			if (last.fi != -1) {
				int d = x.fi-last.fi;
				adj[x.se].push_back({last.se,d});
				adj[last.se].push_back({x.se,d});
			}
			last = x;
		}
	}
	PQ.push({0,1});
	for (int i=2;i<=T;i++) {
		dist[i] = INF;
	}
	while (!PQ.empty()) {
		pli x = PQ.top();
		PQ.pop();
		if (dist[x.se] != x.fi) continue;
		for (pii y : adj[x.se]) {
			if (dist[y.fi] <= x.fi + y.se) continue;
			dist[y.fi] = x.fi + y.se;
			PQ.push({dist[y.fi],y.fi});
		}
	}
	if (dist[2] == INF) {
		return -1;
	}
	return dist[2];
}
#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...