This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
// M
#include<bits/stdc++.h>
#include "walk.h"
#define lc (id << 1)
#define rc (lc ^ 1)
#define md ((l + r) >> 1)
#define pb push_back
using namespace std;
typedef long long ll;
const int N = 100005, MXM = N * 5, MXN = MXM * 2;
int n, ts, A[N], MX[N * 4], Lid[MXM], Rid[MXM];
vector < int > S[N], E[N], V[N], ID[N];
vector < pair < int , ll > > Adj[MXN];
ll D[MXN];
inline void AddEdge(int v, int u, ll w)
{
        assert(w >= 0);
        Adj[v].pb({u, w});
        Adj[u].pb({v, w});
}
void Build(int id = 1, int l = 0, int r = n)
{
        if (r - l < 2)
                return void(MX[id] = A[l]);
        Build(lc, l, md);
        Build(rc, md, r);
        MX[id] = max(MX[lc], MX[rc]);
}
int GetFirst(int i, int val, int id = 1, int l = 0, int r = n)
{
        if (r <= i || MX[id] < val)
                return -1;
        if (r - l < 2)
                return l;
        int rt = GetFirst(i, val, lc, l, md);
        if (rt != -1)
                return rt;
        return GetFirst(i, val, rc, md, r);
}
int GetLast(int i, int val, int id = 1, int l = 0, int r = n)
{
        if (i < l || MX[id] < val)
                return -1;
        if (r - l < 2)
                return l;
        int rt = GetLast(i, val, rc, md, r);
        if (rt != -1)
                return rt;
        return GetLast(i, val, lc, l, md);
}
ll min_distance(vector < int > X, vector < int > H, vector < int > L, vector < int > R, vector < int > Y, int st, int fn)
{
        n = (int)X.size();
        for (int i = 0; i < n; i ++)
                A[i] = H[i];
        Build();
        if (st > fn)
                swap(st, fn);
        if (st == fn)
                return 0LL;
        for (int i = 0; i < (int)L.size(); i ++)
                if (L[i] < st && st < R[i])
                {
                        int l = GetLast(st, Y[i]);
                        int r = GetFirst(st, Y[i]);
                        assert(l != -1 && r != -1);
                        assert(l >= L[i] && r <= R[i]);
                        if (L[i] < l)
                                L.pb(L[i]), R.pb(l), Y.pb(Y[i]);
                        if (r < R[i])
                                L.pb(r), R.pb(R[i]), Y.pb(Y[i]);
                        L[i] = l; R[i] = r;
                }
        for (int i = 0; i < (int)L.size(); i ++)
                if (L[i] == R[i])
                {
                        swap(L[i], L.back()); L.pop_back();
                        swap(R[i], R.back()); R.pop_back();
                        swap(Y[i], Y.back()); Y.pop_back();
                        i --;
                }
        for (int i = 0; i < (int)L.size(); i ++)
                if (L[i] < fn && fn < R[i])
                {
                        int l = GetLast(fn, Y[i]);
                        int r = GetFirst(fn, Y[i]);
                        assert(l != -1 && r != -1);
                        assert(l >= L[i] && r <= R[i]);
                        if (L[i] < l)
                                L.pb(L[i]), R.pb(l), Y.pb(Y[i]);
                        if (r < R[i])
                                L.pb(r), R.pb(R[i]), Y.pb(Y[i]);
                        L[i] = l; R[i] = r;
                }
        for (int i = 0; i < (int)L.size(); i ++)
                if (L[i] == R[i])
                {
                        swap(L[i], L.back()); L.pop_back();
                        swap(R[i], R.back()); R.pop_back();
                        swap(Y[i], Y.back()); Y.pop_back();
                        i --;
                }
        for (int i = 0; i < (int)L.size(); i ++)
                S[L[i]].pb(i), E[R[i]].pb(i);
        for (int i = 0; i < n; i ++)
        {
                if (i == st || i == fn)
                        V[i].pb(0);
                for (int j : S[i])
                        V[i].pb(Y[j]);
                for (int j : E[i])
                        V[i].pb(Y[j]);
                sort(V[i].begin(), V[i].end());
                V[i].resize(unique(V[i].begin(), V[i].end()) - V[i].begin());
                for (int j : V[i])
                        ID[i].pb(ts ++);
        }
        for (int i = 0; i < (int)L.size(); i ++)
        {
                Lid[i] = ID[L[i]][(int)(lower_bound(V[L[i]].begin(), V[L[i]].end(), Y[i]) - V[L[i]].begin())];
                Rid[i] = ID[R[i]][(int)(lower_bound(V[R[i]].begin(), V[R[i]].end(), Y[i]) - V[R[i]].begin())];
        }
        set < pair < int , int > > ST;
        for (int i = 0; i < n; i ++)
        {
                for (int j : E[i])
                        ST.erase({Y[j], j});
                for (int j = 1; j < (int)V[i].size(); j ++)
                        AddEdge(ID[i][j - 1], ID[i][j], V[i][j] - V[i][j - 1]);
                for (int j = 0; j < (int)V[i].size(); j ++)
                {
                        auto it = ST.lower_bound({V[i][j], -1});
                        if (it != ST.begin())
                        {
                                it --;
                                assert(it->first < V[i][j]);
                                AddEdge(ts, ID[i][j], V[i][j] - it->first);
                                AddEdge(Lid[it->second], ts, X[i] - X[L[it->second]]);
                                Lid[it->second] = ts;
                                L[it->second] = i;
                                ts ++; it ++;
                        }
                        if (it != ST.end() && it->first <= H[i])
                        {
                                assert(it->first >= V[i][j]);
                                AddEdge(ts, ID[i][j], it->first - V[i][j]);
                                AddEdge(Lid[it->second], ts, X[i] - X[L[it->second]]);
                                Lid[it->second] = ts;
                                L[it->second] = i;
                                ts ++;
                        }
                }
                for (int j : S[i])
                        ST.insert({Y[j], j});
        }
        for (int i = 0; i < (int)L.size(); i ++)
                AddEdge(Lid[i], Rid[i], X[R[i]] - X[L[i]]);
        priority_queue < pair < ll , int > > Pq;
        memset(D, 63, sizeof(D));
        D[ID[st][0]] = 0;
        Pq.push({0, ID[st][0]});
        while (Pq.size())
        {
                ll d = -Pq.top().first;
                int v = Pq.top().second;
                Pq.pop();
                if (v == ID[fn][0])
                        return d;
                if (d > D[v])
                        continue;
                for (auto u : Adj[v])
                        if (D[u.first] > D[v] + u.second)
                                D[u.first] = D[v] + u.second, Pq.push({-D[u.first], u.first});
        }
        return -1LL;
}
Compilation message (stderr)
walk.cpp: In function 'll min_distance(std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, int, int)':
walk.cpp:117:26: warning: unused variable 'j' [-Wunused-variable]
  117 |                 for (int j : V[i])
      |                          ^| # | 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... |