This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "walk.h"
#include <bits/stdc++.h>
using namespace std;
typedef pair<long long, long long> ii;
long long inf = (1LL << 62LL);
///X, Y refers to points & buildings. L, R, H refers to skywalks
struct walk { long long l, r, h; };
struct vertex { long long x, y, id; };
long long min_distance(vector<int> X, vector<int> Y, vector<int> L, vector<int> R, vector<int> H, int START, int END) {
	long long n = X.size(), m = L.size();
	walk skywalks[m];
	for(long long i = 0;i < m;i++) skywalks[i] = {L[i], R[i], H[i]};
	
	vector<long long> useful[n];
	useful[START].push_back(0);
	useful[END].push_back(0);
	
	for(walk w : skywalks){
		useful[w.l].push_back(w.h);
		useful[w.r].push_back(w.h);
	}
	
	///For skywalks crossing START and END, Split them
	set<long long> aboveLine; ///A sweeping line going from bottom to top;
	
	vector<long long> walkHeight; ///walk indeces sorted in increasing H
	for(long long i = 0;i < m;i++) walkHeight.push_back(i);
	sort(walkHeight.begin(), walkHeight.end(), [&](long long a, long long b) { return H[a] < H[b]; });
	
	vector<ii> buildingHeight; ///building indeces soreted in increasing Y
	for(long long i = 0;i < n;i++){
		buildingHeight.push_back(ii(Y[i], i));
		aboveLine.insert(i);
	}
	sort(buildingHeight.begin(), buildingHeight.end());
	long long ptr = 0;
	
	for(long long i = 0;i < m;i++){
		long long w = walkHeight[i];
		while(ptr < n && buildingHeight[ptr].first < H[w]){
			aboveLine.erase(buildingHeight[ptr].second);
			ptr++;
		}
		
		if(L[w] <= START && START <= R[w]){
			auto it = aboveLine.lower_bound(START);
			if(*it == START){
				useful[START].push_back(H[w]);
			}
			else{
				useful[*it].push_back(H[w]);
				it--;
				useful[*it].push_back(H[w]);
			}
		}
		
		if(L[w] <= END && END <= R[w]){
			auto it = aboveLine.lower_bound(END);
			if(*it == END){
				useful[END].push_back(H[w]);
			}
			else{
				useful[*it].push_back(H[w]);
				it--;
				useful[*it].push_back(H[w]);
			}
		}
		
	}
	
	vector<ii> event[n]; ///process walks from left to right
	for(walk w : skywalks){
		event[w.l].push_back(ii(w.h, 1));
		if(w.r != n-1) event[w.r+1].push_back(ii(w.h, -1));
	}
	
	multiset<long long> walkHeights;
	for(long long i = 0;i < n;i++){ 
		for(ii Ev : event[i]){
			if(Ev.second == 1) walkHeights.insert(Ev.first);
			else walkHeights.erase(walkHeights.find(Ev.first));
		}
		
		vector<long long> moreUseful; ///extra points to add to useful[i]
		
		for(long long h : useful[i]){
			multiset<long long>::iterator it = walkHeights.upper_bound(h);
			//if(it != walkHeights.end()) moreUseful.push_back(*it);
			if(it == walkHeights.begin()) continue;
			it--;
			if(it != walkHeights.begin()) moreUseful.push_back(*(--it));
		}
		
		for(long long u : moreUseful) useful[i].push_back(u);
		sort(useful[i].begin(),useful[i].end());
		useful[i].erase(unique(useful[i].begin(),useful[i].end()), useful[i].end());
		while(useful[i].size() > 0 && useful[i].back() > Y[i]) useful[i].pop_back();
	}
	
	
	vector<vertex> vertices;
	long long S, E; ///Start and End based on renumbering
	long long idx = 0;
	
	for(long long i = 0;i < n;i++){
		if(i == START) S = idx;
		if(i == END) E = idx;
		for(long long y : useful[i]){
			vertices.push_back({X[i], y, idx}); 
			idx++;
		}
	}
	
	long long N = vertices.size(); ///big N is for no. of nodes on the graph
	vector<ii> adj[N];
	long long vis[N];
	fill(vis, vis + N, inf);
	
	for(long long i = 1;i < N;i++){
		if(vertices[i].x == vertices[i-1].x){
			long long w = vertices[i].y - vertices[i-1].y;
			adj[i].push_back(ii(w,i-1));
			adj[i-1].push_back(ii(w,i));
		}
	}
	
	auto compY = [&](vertex a, vertex b){ return ii(a.y,a.x) < ii(b.y,b.x); };
	sort(vertices.begin(),vertices.end(),compY);
	
	for(walk w : skywalks){
		int pos = lower_bound(vertices.begin(),vertices.end(), (vertex){X[w.l], w.h, -1} ,compY) - vertices.begin();
		while(vertices[pos].x < X[w.r]){
			long long u = vertices[pos].id;
			pos++;
			long long v = vertices[pos].id;
			long long w = vertices[pos].x - vertices[pos-1].x;
			adj[u].push_back(ii(w,v));
			adj[v].push_back(ii(w,u));
		}
	}
	
	///Dijkstra
	priority_queue<ii, vector<ii>, greater<ii> > dij;
	dij.push(ii(0,S)); vis[S] = 0;
	while(!dij.empty()){
		ii u = dij.top(); dij.pop();
		for(ii v : adj[u.second]){
			if(vis[v.second] > u.first + v.first){
				vis[v.second] = u.first + v.first;
				dij.push(ii(vis[v.second], v.second));
			}
		}
	}
	
	if(vis[E] >= inf) vis[E] = -1;
	return vis[E];
}
Compilation message (stderr)
walk.cpp: In function 'long long int min_distance(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, int, int)':
walk.cpp:147:28: warning: 'S' may be used uninitialized in this function [-Wmaybe-uninitialized]
  dij.push(ii(0,S)); vis[S] = 0;
                     ~~~~~~~^~~
walk.cpp:105:15: warning: 'E' may be used uninitialized in this function [-Wmaybe-uninitialized]
  long long S, E; ///Start and End based on renumbering
               ^| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |