Problem p03153 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T> struct Kruskal {

  struct edge {
    Int from, to;
    T cost;
    Int used;
    edge() {}
    edge(Int from, Int to, T cost) : from(from), to(to), cost(cost), used(0) {}
    bool operator<(const edge &e) const { return cost < e.cost; }
  };

  Int n;
  vector<Int> p, r;
  vector<edge> edges;

  Kruskal() {}
  Kruskal(Int n) : n(n) {}

  void init(Int n) {
    r.assign(n, 1);
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }

  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }

  bool same(Int x, Int y) { return find(x) == find(y); }

  void unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }

  void add_edge(Int u, Int v, T c) { edges.emplace_back(u, v, c); }

  T build() {
    sort(edges.begin(), edges.end());
    init(n);
    T res = 0;
    for (auto &e : edges) {
      if (!same(e.from, e.to)) {
        res += e.cost;
        unite(e.from, e.to);
        e.used = 1;
      }
    }
    return res;
  }
};

struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;

// INSERT ABOVE HERE
signed main() {
  Int n, d;
  cin >> n >> d;
  vector<Int> a(n);
  for (Int i = 0; i < n; i++)
    cin >> a[i];
  Kruskal<Int> ks(n);
  using P = pair<Int, Int>;

  const Int INF = 1e18;
  vector<P> ls(n, P(INF, -1)), rs(n, P(INF, -1)), dp(n);
  function<void(Int, Int)> dfs = [&](Int l, Int r) -> void {
    if (l + 1 == r) {
      dp[l] = P(a[l], l);
      return;
    }
    Int m = (l + r) >> 1;
    dfs(l, m);
    dfs(m, r);
    P x(INF, -1), y(INF, -1);
    for (Int i = l, j = m; i < m || j < r;) {
      if (j == r || dp[i].first <= dp[j].first) {
        Int k = dp[i++].second;
        chmin(rs[k], y);
        chmin(x, P(a[k] - k * d, k));
      } else {
        Int k = dp[j++].second;
        chmin(ls[k], x);
        chmin(y, P(a[k] + k * d, k));
      }
    }

    inplace_merge(dp.begin() + l, dp.begin() + m, dp.begin() + r);
  };
  dfs(0, n);

  auto add_edge = [&](Int x, Int y) {
    if (x < 0 || y < 0)
      return;
    Int c = abs(x - y) * d + a[x] + a[y];
    ks.add_edge(x, y, c);
  };
  for (Int i = 0; i < n; i++)
    add_edge(ls[i].second, i);
  for (Int i = 0; i < n; i++)
    add_edge(i, rs[i].second);

  cout << ks.build() << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T> struct Kruskal {

  struct edge {
    Int from, to;
    T cost;
    Int used;
    edge() {}
    edge(Int from, Int to, T cost) : from(from), to(to), cost(cost), used(0) {}
    bool operator<(const edge &e) const { return cost < e.cost; }
  };

  Int n;
  vector<Int> p, r;
  vector<edge> edges;

  Kruskal() {}
  Kruskal(Int n) : n(n) {}

  void init(Int n) {
    r.assign(n, 1);
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }

  Int find(Int x) { return (x == p[x] ? x : p[x] = find(p[x])); }

  bool same(Int x, Int y) { return find(x) == find(y); }

  void unite(Int x, Int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }

  void add_edge(Int u, Int v, T c) { edges.emplace_back(u, v, c); }

  T build() {
    sort(edges.begin(), edges.end());
    init(n);
    T res = 0;
    for (auto &e : edges) {
      if (!same(e.from, e.to)) {
        res += e.cost;
        unite(e.from, e.to);
        e.used = 1;
      }
    }
    return res;
  }
};

struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;

// INSERT ABOVE HERE
signed main() {
  Int n, d;
  cin >> n >> d;
  vector<Int> a(n);
  for (Int i = 0; i < n; i++)
    cin >> a[i];
  Kruskal<Int> ks(n);
  using P = pair<Int, Int>;

  const Int INF = 1e18;
  vector<P> ls(n, P(INF, -1)), rs(n, P(INF, -1)), dp(n);
  function<void(Int, Int)> dfs = [&](Int l, Int r) -> void {
    if (l + 1 == r) {
      dp[l] = P(a[l], l);
      return;
    }
    Int m = (l + r) >> 1;
    dfs(l, m);
    dfs(m, r);
    P x(INF, -1), y(INF, -1);
    for (Int i = l, j = m; i < m || j < r;) {
      if (i < m && (j == r || dp[i].first <= dp[j].first)) {
        Int k = dp[i++].second;
        chmin(rs[k], y);
        chmin(x, P(a[k] - k * d, k));
      } else {
        Int k = dp[j++].second;
        chmin(ls[k], x);
        chmin(y, P(a[k] + k * d, k));
      }
    }

    inplace_merge(dp.begin() + l, dp.begin() + m, dp.begin() + r);
  };
  dfs(0, n);

  auto add_edge = [&](Int x, Int y) {
    if (x < 0 || y < 0)
      return;
    Int c = abs(x - y) * d + a[x] + a[y];
    ks.add_edge(x, y, c);
  };
  for (Int i = 0; i < n; i++)
    add_edge(ls[i].second, i);
  for (Int i = 0; i < n; i++)
    add_edge(i, rs[i].second);

  cout << ks.build() << endl;
  return 0;
}