이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
class Graph {
 private:
  struct edge_t {
    int v;
    long long w;
    edge_t() {}
    edge_t(int v, long long w) : v(v), w(w) {}
    bool operator < (const edge_t &o) const { return w > o.w; }
  };
  vector<vector<edge_t>> adj;
 public:
  Graph() {}
  int AddVertex() {
    adj.emplace_back();
    return (int) adj.size() - 1;
  }
  void AddEdge(int u, int v, long long w) {
    adj[u].emplace_back(v, w);
    adj[v].emplace_back(u, w);
  }
  long long Dijkstra(int s, int g) {
    priority_queue<edge_t> pq;
    vector<long long> dist(adj.size(), -1);
    pq.emplace(s, 0);
    dist[s] = 0;
    while (!pq.empty()) {
      int u = pq.top().v;
      long long d = pq.top().w;
      pq.pop();
      if (dist[u] != d) continue;
      for (auto e : adj[u]) {
        if (dist[e.v] == -1 || dist[e.v] > dist[u] + e.w) {
          dist[e.v] = dist[u] + e.w;
          pq.emplace(e.v, dist[e.v]);
        }
      }
    }
    return dist[g];
  }
};
struct Point {
  int x, y;
  Point() {}
  Point(int x, int y) : x(x), y(y) {}
  bool operator < (const Point &o) const { return make_pair(x, y) < make_pair(o.x, o.y); }
  bool operator > (const Point &o) const { return make_pair(x, y) > make_pair(o.x, o.y); }
  bool operator == (const Point &o) const { return x == o.x && y == o.y; }
};
class Planar {
 private:
  Graph G;
  map<Point, int> id;
 public:
  Planar() {}
  void AddVertex(Point p) {
    if (!id.count(p)) id.emplace(p, G.AddVertex());
  }
  void AddEdge(Point a, Point b) {
    if (a == b) return;
    AddVertex(a), AddVertex(b);
    G.AddEdge(id[a], id[b], abs(a.x - b.x) + abs(a.y - b.y));
  }
  long long Dijkstra(Point s, Point g) {
    AddVertex(s), AddVertex(g);
    return G.Dijkstra(id[s], id[g]);
  }
};
long long min_distance(vector<int> x, vector<int> h, vector<int> l, 
                       vector<int> r, vector<int> y, int s, int g) {
  Planar G;
  auto SplitSkywalk = [&](int p) { // Split skywalks that passes over p into separate parts
    struct event_t {
      int t; // type 0 = skywalk, 1 = building
      int id;
      int h, l, r;
      event_t() {}
      event_t(int t, int id, int h, int l, int r) : t(t), id(id), h(h), l(l), r(r) {}
    };
    int n = x.size(), m = y.size();
    vector<int> new_l;
    vector<int> new_r;
    vector<int> new_y;
    vector<event_t> events; 
    for (int i = 0; i < m; i++) {
      events.emplace_back(0, i, y[i], l[i], r[i]);
    }
    for (int i = 0; i < n; i++) {
      events.emplace_back(1, i, h[i], i, i);
    }
    
    set<int> active; // active buildings
    for (int i = 0; i < n; i++) {
      active.emplace(i);
    }
    sort(begin(events), end(events), [&](const event_t &a, const event_t &b) {
      return make_pair(a.h, a.t) < make_pair(b.h, b.t);
    });
    for (auto event : events) {
      if (event.t == 0) { // skywalk
        if (event.r < p || p < event.l) { // doesn't pass over p
          new_y.emplace_back(event.h);
          new_l.emplace_back(event.l);
          new_r.emplace_back(event.r);
          continue;
        }
        auto lb = active.lower_bound(p);
        auto ub = active.upper_bound(p);
        int on_left = (ub == begin(active) ? -1 : *prev(ub));
        int on_right = (lb == end(active) ? -1 : *lb);
        if (event.l <= on_left && on_right <= event.r) {
          new_y.emplace_back(event.h);
          new_l.emplace_back(event.l);
          new_r.emplace_back(on_left);
          new_y.emplace_back(event.h);
          new_l.emplace_back(on_left);
          new_r.emplace_back(on_right);
          
          new_y.emplace_back(event.h);
          new_l.emplace_back(on_right);
          new_r.emplace_back(event.r);
        }
      } else { // building
        active.erase(event.id);
      }
    }
    l = new_l, r = new_r, y = new_y;
  };
  
  auto BuildGraph = [&]() { // For each endpoint of skywalks, add vertices on the skywalk above and below the current one
    l.emplace_back(s);
    r.emplace_back(s);
    y.emplace_back(0);
    l.emplace_back(g);
    r.emplace_back(g);
    y.emplace_back(0);
    int n = x.size(), m = y.size();
    vector<vector<pair<int, int>>> events(n); // (height, id)
    vector<int> last_point(m); // last point added on the i-th skywalk
    for (int i = 0; i < m; i++) {
      events[l[i]].emplace_back(+y[i], i); // add new skywalk starting from at l[i]
      events[r[i]].emplace_back(-y[i], i); // delete skywalks ending at r[i]
      last_point[i] = x[l[i]];
    }
    set<pair<int, int>> ys; // (height, id)
    ys.emplace(-1, -1);
    for (int i = 0; i < n; i++) {
      sort(begin(events[i]), end(events[i]), greater<pair<int, int>>());
      for (auto event : events[i]) {
        int y = abs(event.first), id = event.second;
        auto lb = ys.lower_bound({y, -1});
        auto ub = ys.upper_bound({y, m});
        
        int above = (ub == end(ys) ? -1 : ub->first);
        int id_above = (ub == end(ys) ? -1 : ub->second);
        
        int below = (lb == begin(ys) ? -1 : prev(lb)->first);
        int id_below = (lb == begin(ys) ? -1 : prev(lb)->second);
        
        if (above != -1 && above <= h[i]) {
          G.AddEdge(Point(x[i], y), Point(x[i], above));
          G.AddEdge(Point(last_point[id_above], above), Point(x[i], above));
          last_point[id_above] = x[i];
        }
        
        if (below != -1) {
          G.AddEdge(Point(x[i], y), Point(x[i], below));
          G.AddEdge(Point(last_point[id_below], below), Point(x[i], below));
          last_point[id_below] = x[i];
        }
        if (event.first > 0) {
          ys.emplace(y, id);
        } else if (event.first < 0) {
          G.AddEdge(Point(x[i], y), Point(last_point[id], y));
          ys.erase({y, id});
        }
      }
    }
  };
  SplitSkywalk(s);
  SplitSkywalk(g);
  BuildGraph();
  return G.Dijkstra(Point(x[s], 0), Point(x[g], 0));
}
| # | 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... |