제출 #1369812

#제출 시각아이디문제언어결과실행 시간메모리
1369812viduxSky Walking (IOI19_walk)C++17
24 / 100
4111 ms586396 KiB
#include "walk.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Seg {
	int n;
	vector<int> t;
	Seg(int sz) {
		n = sz;
		t = vector<int>(2*n);
	}
	void update(int p, int v) {
		for (t[p += n] = v; p > 1; p /= 2) t[p/2] = max(t[p], t[p^1]);
	}
	int query(int l, int r) {
		int ret = 0;
		for (l += n, r += n; l < r; l /= 2, r /= 2) {
			if (l&1) ret = max(ret, t[l++]);
			if (r&1) ret = max(ret, t[--r]);
		}
		return ret;
	}
	int upper_bound(int l, int v) {
		int lo = l+1, hi = n-1;
		int bnd = l;
		while (lo <= hi) {
			int m = (lo+hi)/2;
			int q = query(l+1, m+1);
			if (q < v) bnd = m, lo = m+1;
			else hi = m-1;
		}
		return bnd+1;
	}
};
long long min_distance(std::vector<int> x, std::vector<int> h, std::vector<int> l, std::vector<int> r, std::vector<int> y, int s, int g) {
	int n = (int)x.size();
	int m = (int)y.size();
	map<pair<int, int>, vector<pair<pair<int, int>, int>>> mp;
	vector<set<int>> pts(n, {0});
	Seg seg(n);
	for (int i = 0; i < n; i++) seg.update(i, h[i]);
	for (int i = 0; i < m; i++) {
		int j = l[i];
		while (1) {
			int j2 = seg.upper_bound(j, y[i]);
			if (j2 > r[i]) break;
			//cout << i << " -> " << j << " " << j2 << endl;
			mp[pair<int, int>{j, y[i]}].push_back({pair<int, int>{j2, y[i]}, x[j2]-x[j]});
			mp[pair<int, int>{j2, y[i]}].push_back({pair<int, int>{j, y[i]}, x[j2]-x[j]});
			pts[j].insert(y[i]);
			pts[j2].insert(y[i]);
			j = j2;
		}
	}
	map<pair<int, int>, ll> dist;
	for (int i = 0; i < n; i++) {
		int pr = -1;
		for (int y : pts[i]) {
			if (pr != -1) {
				mp[pair<int, int>{i, y}].push_back({pair<int, int>{i, pr}, y-pr});
				mp[pair<int, int>{i, pr}].push_back({pair<int, int>{i, y}, y-pr});
			}
			pr = y;
			dist[pair<int, int>{i, y}] = 1e18;
		}
	}
	priority_queue<pair<ll, pair<int, int>>, vector<pair<ll, pair<int, int>>>, greater<pair<ll, pair<int, int>>>> pq;
	pq.push({0ll, {s, 0}});
	dist[{s, 0}] = 0ll;
	//cout << "Adj: " << endl;;
	//for (auto [pt, v] : mp) for (auto pt2d:v) {
	//	cout << pt.first << " " << pt.second << ": " << pt2d.first.first << " " << pt2d.first.second << " w:" << pt2d.second << endl;
	//}
	while (pq.size()) {
		auto [d, pt] = pq.top(); pq.pop();
		if (d != dist[pt]) continue;
		for (auto [npt, w] : mp[pt]) if (dist[npt] > d+w) {
			dist[npt] = d+w;
			pq.push({d+w, npt});
		}
		if (dist[{g, 0}] != 1e18) {
			//cout << endl << "Dist: " << endl;
			//for (auto [pt, d] : dist) {
			//	cout << pt.first << " " << pt.second << ": " << d << endl;
			//}
			return dist[{g, 0}];
		}
	}
	return -1;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…