이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#define BUGO(x) cerr << #x << " -> " << (x) << endl;
#include "walk.h"
#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
using llong = long long;
vector<pair<int, int>> nei[6900'000];
llong dist[6900'000];
const llong inf = 69'000'000'000'000'000LL;
llong Dijkstra(int s, int e)
{
    fill(dist, dist + 6900'000, inf);
    priority_queue<pair<llong, int>> q;
    q.push({dist[s] = 0, s});
    while (q.size())
    {
        int v = q.top().second;
        llong d = -q.top().first;
        q.pop();
        if (dist[v] != d) continue;
        for (auto to: nei[v])
            if (d + to.second < dist[to.first])
                q.push({-(dist[to.first] = d + to.second), to.first});
    }
    return dist[e] == inf ? -1 : dist[e];
}
map<int, int> nodeOf[100'000];
llong dp[100'000];
struct Comp {
    static vector<int>* h_;
    bool operator()(int l, int r) const {
        return h_->at(l) < h_->at(r);
    }
};
vector<int>* Comp::h_;
long long min_distance(std::vector<int> x, std::vector<int> y, std::vector<int> l, std::vector<int> r,
std::vector<int> h, int s, int e) {
    int n = x.size();
    int m = l.size();
    if ((n <= 50 && m <= 50) || y != vector<int>(n, y[0]))
    {
        int nodes = 0;
        for (int i = 0; i < n; ++i)
            nodeOf[i][y[i]] = nodes++;
        nodeOf[s][0] = nodes++;
        nodeOf[e][0] = nodes++;
        vector<int> towers(n);
        iota(towers.begin(), towers.end(), 0);
        sort(towers.begin(), towers.end(), [&](int l, int r) {
            return y[l] < y[r];
        });
        vector<int> bridges(m);
        iota(bridges.begin(), bridges.end(), 0);
        sort(bridges.begin(), bridges.end(), [&](int l, int r) {
            return h[l] < h[r];
        });
        set<int> activeTowers;
        for (int tch = m - 1; tch >= 0; --tch)
        {
            int j = bridges[tch];
            while (towers.size() && y[towers.back()] >= h[j]) {
                activeTowers.insert(towers.back());
                towers.pop_back();
            }
            int lt = -1;
            for (auto it = activeTowers.lower_bound(l[j]); it != activeTowers.end() && *it <= r[j]; ++it)
            {
                int i = *it;
                if (!nodeOf[i].count(h[j]))
                    nodeOf[i][h[j]] = nodes++;
                if (lt != -1) {
                    int u = nodeOf[i][h[j]];
                    int v = nodeOf[lt][h[j]];
                    nei[u].push_back({v, x[i] - x[lt]});
                    nei[v].push_back({u, x[i] - x[lt]});
                }
                lt = i;
            }
        }
        for (int i = 0; i < n; ++i)
        {
            int ltHei = -1;
            for (auto [hei, node]: nodeOf[i])
            {
                if (ltHei != -1) {
                    int u = nodeOf[i][ltHei];
                    int v = node;
                    nei[u].push_back({v, hei - ltHei});
                    nei[v].push_back({u, hei - ltHei});
                }
                ltHei = hei;
            }
        }
        return Dijkstra(n, n + 1);
    }
    l.push_back(-1);
    r.push_back(0);
    h.push_back(0);
    ++m;
    fill(dp, dp + m, inf);
    dp[m - 1] = 0;
    vector<int> bridges(m);
    iota(bridges.begin(), bridges.end(), 0);
    sort(bridges.begin(), bridges.end(), [&r](int i, int j) {
        return r[i] < r[j];
    });
    vector<pair<int, int>> bridgesUpd;
    for (int j = 0; j < m; ++j) {
        bridgesUpd.push_back({l[j], j});
        bridgesUpd.push_back({r[j], -j});
    }
    sort(bridgesUpd.begin(), bridgesUpd.end());
    Comp::h_ = &h;
    set<int, Comp> activeBridges;
    int j = 0;
    for (int i: bridges)
    {
        if (dp[i] == inf) continue;
        while (j < bridgesUpd.size() && bridgesUpd[j].first <= r[i]) {
            // BUGO(bridgesUpd[j].first)
            int upd = bridgesUpd[j++].second;
            if (upd > 0 || (!upd && !activeBridges.count(upd))) activeBridges.insert(upd);
            else activeBridges.erase(-upd);
        }
        auto it = activeBridges.lower_bound(i);
        if (it != activeBridges.end())
            dp[*it] = min(dp[*it], dp[i] + x[r[*it]] - x[r[i]] + h[*it] - h[i]);
        if (it != activeBridges.begin()) {
            --it;
            dp[*it] = min(dp[*it], dp[i] + x[r[*it]] - x[r[i]] + h[i] - h[*it]);
        }
    }
    llong ans = inf;
    for (int j = 0; j < m; ++j)
        if (r[j] == n - 1)
            ans = min(ans, dp[j] + h[j]);
    return ans == inf ? -1 : ans;
}
컴파일 시 표준 에러 (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:130:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  130 |         while (j < bridgesUpd.size() && bridgesUpd[j].first <= r[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... |