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;
#define ff first
#define ll long long
#define ss second
const int N = 1000'005;
vector<int> br[N];
vector<pair<int, int> > adj[N];
int mx[N];
int n;
void build(vector<int>& h, int id, int l, int r){
if(l == r){
mx[id] = h[l];
return;
}
int m = (l + r) >> 1;
build(h, id << 1, l, m);
build(h, id << 1 | 1, m + 1, r);
mx[id] = max(mx[id << 1], mx[id << 1 | 1]);
}
int find_right(int id, int l, int r, int L, int R, int x){
if(L > r || R < l) return -1;
if(L <= l && r <= R){
if(mx[id] < x) return -1;
if(l == r) return r;
int m = (l + r) >> 1;
if(mx[id << 1 | 1] >= x) return find_right(id << 1 | 1, m + 1, r, L, R, x);
return find_right(id << 1, l, m, L, R, x);
}
int m = (l + r) >> 1;
int s = find_right(id << 1 | 1, m + 1, r, L, R, x);
if(s != -1) return s;
return find_right(id << 1, l, m, L, R, x);
}
int find_left(int id, int l, int r, int L, int R, int x){
if(L > r || R < l) return -1;
if(L <= l && r <= R){
if(mx[id] < x) return -1;
if(l == r) return r;
int m = (l + r) >> 1;
if(mx[id << 1] >= x) return find_left(id << 1, l, m, L, R, x);
return find_left(id << 1 | 1, m + 1, r, L, R, x);
}
int m = (l + r) >> 1;
int s = find_left(id << 1, l, m, L, R, x);
if(s != -1) return s;
return find_left(id << 1 | 1, m + 1, r, L, R, x);
}
vector<pair<int, int> > pos;
vector<pair<int, int> > sweep;
multiset<int> in;
map<pair<int, int>, int> id;
map<int, pair<int, int> > last;
void add(int v, int u, int d){
adj[v].push_back({u, d});
adj[u].push_back({v, d});
}
ll dis[N];
priority_queue<pair<ll, int> > pq;
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) {
n = h.size();
build(h, 1, 0, n - 1);
for(int i = 0; i < l.size(); ++i){
sweep.push_back({l[i], y[i]});
sweep.push_back({l[i] + 1, y[i]});
sweep.push_back({r[i] + 1, -y[i]});
sweep.push_back({r[i] + 1, -y[i]});
pos.push_back({l[i], -y[i]});
pos.push_back({r[i], -y[i]});
if(l[i] < s && s < r[i]){
pos.push_back({find_left(1, 0, n - 1, s, r[i], y[i]), -y[i]});
pos.push_back({find_right(1, 0, n - 1, l[i], s, y[i]), -y[i]});
}
if(l[i] < g && g < r[i]){
pos.push_back({find_left(1, 0, n - 1, g, r[i], y[i]), -y[i]});
pos.push_back({find_right(1, 0, n - 1, l[i], g, y[i]), -y[i]});
}
}
sort(pos.begin(), pos.end());
sort(sweep.begin(), sweep.end());
int i = 0;
in.insert(0);
int tmp = 0;
for(auto& w : pos){
while(i < sweep.size() && sweep[i].ff <= w.ff){
if(sweep[i].ss > 0) in.insert(-sweep[i].ss);
else in.erase(in.find(sweep[i].ss));
++i;
}
int x1 = w.ff, y1 = -w.ss, id1;
int x2 = w.ff, y2 = -(*in.upper_bound(w.ss)), id2;
if((id1 = id[{x1, y1}]) == 0)
id1 = id[{x1, y1}] = ++tmp;
if((id2 = id[{x2, y2}]) == 0)
id2 = id[{x2, y2}] = ++tmp;
add(id1, id2, y1 - y2);
if(in.count(-y1) >= 2)
add(id1, last[y1].ff, x[x1] - x[last[y1].ss]);
if(in.count(-y2) >= 2)
add(id2, last[y2].ff, x[x2] - x[last[y2].ss]);
last[y2] = {id2, x2};
last[y1] = {id1, x1};
}
int b = id[{g, 0}];
for(int i = 0; i < N; ++i)
dis[i] = 2'000'000'000'000'000'000;
dis[b] = 0;
pq.push({0, b});
while(!pq.empty()){
b = pq.top().ss;
if(pq.top().ff != -dis[b]){
pq.pop();
continue;
}
pq.pop();
for(auto& w : adj[b]){
if(dis[w.ff] > dis[b] + w.ss){
dis[w.ff] = dis[b] + w.ss;
pq.push({-dis[w.ff], w.ff});
}
}
}
b = id[{s, 0}];
return dis[b] == 0 || dis[b] == 2'000'000'000'000'000'000 ? -1 : dis[b];
}
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:75:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int i = 0; i < l.size(); ++i){
~~^~~~~~~~~~
walk.cpp:101:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while(i < sweep.size() && sweep[i].ff <= w.ff){
~~^~~~~~~~~~~~~~
# | 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... |