제출 #1344600

#제출 시각아이디문제언어결과실행 시간메모리
1344600Jawad_Akbar_JJSky Walking (IOI19_walk)C++20
0 / 100
4085 ms27308 KiB
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <algorithm>

using namespace std;
const int N = 1<<17;
vector<pair<int, int>> nei[N * 18], vs[2], vg[2];
vector<int> ins[N], ers[N], L, R;
map<int, int> hor[N], ver[N];
long long Mn[N * 18];
int cur;

int FindVer(int i, int j){
	int &vl = ver[i][j];
	if (vl == 0)
		vl = cur++;
	return vl;
}
void FindHor(int i, int j, int y){
	if (L[i] > j or j > R[i])
		return;
	int &vl = hor[i][j];
	if (vl == 0)
		vl = FindVer(j, y);
}

long long min_distance(vector<int> x, vector<int> h, vector<int> l, vector<int> r, vector<int> y, int s, int g){
	int n = x.size(), m = l.size();
	L = l, R = r;
		
	auto make = [=](vector<pair<int, int>> &v, int st, int en, int stp){
		for (int i=st, mx = 0; i != en; i += stp)
			if (h[i] > mx)
				mx = h[i], v.push_back({mx, i});
	};
	make(vs[0], s, -1, -1);
	make(vs[1], s, n, 1);
	make(vg[0], g, -1, -1);
	make(vg[1], g, n, 1);
	////////////////////////////////////////////////////////////

	for (int i=0;i<m;i++){
		ins[l[i]].push_back(i);
		ers[r[i]].push_back(i);
		FindHor(i, l[i], y[i]);
		FindHor(i, r[i], y[i]);

		auto add = [=](vector<pair<int, int>> &v){
			auto u = upper_bound(begin(v), end(v), make_pair(y[i], -1));
			if (u != end(v) and l[i] <= (*u).second and (*u).second <= r[i])
				FindHor(i, (*u).second, y[i]);
		};
		add(vs[0]);
		add(vs[1]);
		add(vg[0]);
		add(vg[1]);
	}

	set<pair<int, int>> ms;
	for (int i=0;i<n;i++){
		for (int j : ins[i])
			ms.insert({y[j], j});

		set<int> cnd;
		for (auto pr : ver[i]){
			auto u = ms.upper_bound({pr.first+1, -1});
			if (u != ms.end() and (*u).first <= h[i])
				cnd.insert((*u).second);
			if (u == begin(ms))
				continue;
			if ((*u).first == pr.first){
				if (u == begin(ms))
					continue;
				u = prev(u);
			}
			cnd.insert((*u).second);
		}
		for (int j : ers[i])
			ms.erase({y[j], j});

		for (int j : cnd)
			FindHor(j, i, y[j]);
	}

	for (int i=0;i<n;i++){
		if (i == s or i == g)
			FindVer(i, 0);
		pair<int, int> lst = {-1, -1};
		// cout<<i<<" :: ";
		for (auto Now : ver[i]){
			if (Now.first > h[i])
				break;
			if (lst.first != -1){
				int D = Now.first - lst.first;
				// cout<<i<<','<<lst.first<<" --> "<<i<<','<<Now.first<<" | ";
				nei[lst.second].push_back({Now.second, D});
				nei[Now.second].push_back({lst.second, D});
			}
			lst = Now;
		}
		// cout<<endl;
	}

	for (int i=0;i<n;i++){
		pair<int, int> lst = {-1, -1};
		// cout<<i<<" ::: ";
		for (auto Now : hor[i]){
			if (lst.first != -1){
				int D = x[Now.first] - x[lst.first];
				// cout<<lst.first<<','<<y[lst.first]<<" --> "<<Now.first<<','<<y[Now.first]<<" | ";
				nei[lst.second].push_back({Now.second, D});
				nei[Now.second].push_back({lst.second, D});
			}
			lst = Now;
		}
		// cout<<endl;
	}

	for (int i=0;i<=cur;i++)
		Mn[i] = 1e15;
	Mn[ver[s][0]] = 0;
	priority_queue<pair<long long, int>> pq;
	pq.push({0, ver[s][0]});

	while (pq.size() > 0){
		auto [mn, u] = pq.top();
		pq.pop();
		mn = -mn;

		if (mn != Mn[u])
			continue;
		for (auto [i, w] : nei[u]){
			if (Mn[i] > Mn[u] + w)
				Mn[i] = Mn[u] + w, pq.push({-Mn[i], i});
		}
	}
	return (Mn[ver[g][0]] == 1e15 ? -1 : Mn[ver[g][0]]);
}
#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...