Problem p03802 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

struct Segtree {
  int n, V;

  Segtree(int n_input, vector<int> edges[]) {
    n = 1;
    while (n < n_input)
      n <<= 1;
    V = 2 * n - 1;
    for (int k = 0; k < n - 1; k++) {
      edges[k + V].push_back(2 * k + 1 + V);
      edges[k + V].push_back(2 * k + 2 + V);
    }
  }

  void between(int a, int b, int s, vector<int> edges[]) {
    return query(a, b + 1, 0, 0, n, s, edges);
  }

  void query(int a, int b, int k, int l, int r, int s, vector<int> edges[]) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      edges[s + n - 1].push_back(k + V);
      return;
    }
    query(a, b, 2 * k + 1, l, (l + r) / 2, s, edges);
    query(a, b, 2 * k + 2, (l + r) / 2, r, s, edges);
  }
};

struct SCC {
  int N;
  vector<bool> used;
  vector<int> vs;
  vector<int> cmp;

  void dfs(int v, const vector<int> G[]) {
    used[v] = true;
    for (auto u : G[v]) {
      if (!used[u])
        dfs(u, G);
    }
    vs.push_back(v);
  }

  void rdfs(int v, int k, const vector<vector<int>> &rG) {
    used[v] = true;
    cmp[v] = k;
    for (auto u : rG[v]) {
      if (!used[u])
        rdfs(u, k, rG);
    }
  }

  void calculate(int Nin, const vector<int> G[]) {
    N = Nin;
    vector<vector<int>> rG(N);
    for (int i = 0; i < N; i++)
      for (int j : G[i])
        rG[j].push_back(i);
    used.resize(N);
    fill(used.begin(), used.end(), false);
    for (int v = 0; v < N; v++) {
      if (!used[v])
        dfs(v, G);
    }

    fill(used.begin(), used.end(), false);
    cmp.resize(N);
    int k = 0;
    for (int i = vs.size() - 1; i >= 0; i--) {
      if (!used[vs[i]])
        rdfs(vs[i], k++, rG);
    }
  }

  int dump_graph(const vector<int> G[], vector<int> edges2[]) {
    for (int i = 0; i < N; i++) {
      for (auto j : G[i]) {
        if (cmp[i] != cmp[j]) {
          edges2[cmp[i]].push_back(cmp[j]);
        }
      }
    }
    return *max_element(cmp.begin(), cmp.end()) + 1;
  }
};

int N;
vector<pair<int, int>> A;
vector<int> Z;
vector<vector<int>> P;

bool check(int X) {
  vector<int> edges[60000];
  Segtree st(2 * N, edges);
  int offset = st.n - 1, V = st.V;
  for (int i = 0; i < N; i++) {
    int a = offset + P[i][0], b = offset + P[i][1];
    edges[a + V].push_back(b);
    edges[b + V].push_back(a);
  }
  for (int i = 0; i < 2 * N; i++) {
    int l = lower_bound(Z.begin(), Z.end(), Z[i] - X + 1) - Z.begin();
    int r = lower_bound(Z.begin(), Z.end(), Z[i] + X) - Z.begin() - 1;
    st.between(l, i - 1, i, edges);
    st.between(i + 1, r, i, edges);
  }
  SCC scc;
  scc.calculate(2 * V, edges);
  for (int i = 0; i < V; i++)
    if (scc.cmp[i] == scc.cmp[i + V])
      return false;
  return true;
}

int main() {
  cin >> N;
  for (int i = 0; i < N; i++) {
    int x, y;
    cin >> x >> y;
    A.emplace_back(x, i);
    A.emplace_back(y, i);
  }
  sort(A.begin(), A.end());
  P.resize(N);
  for (int i = 0; i < 2 * N; i++) {
    Z.push_back(A[i].first);
    P[A[i].second].push_back(i);
  }

  int ok = 0, ng = 1e9 + 1;
  while (ng - ok > 1) {
    int mid = (ok + ng) / 2;
    (check(mid) ? ok : ng) = mid;
  }
  cout << ok << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

struct Segtree {
  int n, V;

  Segtree(int n_input, vector<int> edges[]) {
    n = 1;
    while (n < n_input)
      n <<= 1;
    V = 2 * n - 1;
    for (int k = 0; k < n - 1; k++) {
      edges[k + V].push_back(2 * k + 1 + V);
      edges[k + V].push_back(2 * k + 2 + V);
    }
  }

  void between(int a, int b, int s, vector<int> edges[]) {
    return query(a, b + 1, 0, 0, n, s, edges);
  }

  void query(int a, int b, int k, int l, int r, int s, vector<int> edges[]) {
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      edges[s + n - 1].push_back(k + V);
      return;
    }
    query(a, b, 2 * k + 1, l, (l + r) / 2, s, edges);
    query(a, b, 2 * k + 2, (l + r) / 2, r, s, edges);
  }
};

struct SCC {
  int N;
  vector<bool> used;
  vector<int> vs;
  vector<int> cmp;

  void dfs(int v, const vector<int> G[]) {
    used[v] = true;
    for (auto u : G[v]) {
      if (!used[u])
        dfs(u, G);
    }
    vs.push_back(v);
  }

  void rdfs(int v, int k, const vector<vector<int>> &rG) {
    used[v] = true;
    cmp[v] = k;
    for (auto u : rG[v]) {
      if (!used[u])
        rdfs(u, k, rG);
    }
  }

  void calculate(int Nin, const vector<int> G[]) {
    N = Nin;
    vector<vector<int>> rG(N);
    for (int i = 0; i < N; i++)
      for (int j : G[i])
        rG[j].push_back(i);
    used.resize(N);
    fill(used.begin(), used.end(), false);
    for (int v = 0; v < N; v++) {
      if (!used[v])
        dfs(v, G);
    }

    fill(used.begin(), used.end(), false);
    cmp.resize(N);
    int k = 0;
    for (int i = vs.size() - 1; i >= 0; i--) {
      if (!used[vs[i]])
        rdfs(vs[i], k++, rG);
    }
  }

  int dump_graph(const vector<int> G[], vector<int> edges2[]) {
    for (int i = 0; i < N; i++) {
      for (auto j : G[i]) {
        if (cmp[i] != cmp[j]) {
          edges2[cmp[i]].push_back(cmp[j]);
        }
      }
    }
    return *max_element(cmp.begin(), cmp.end()) + 1;
  }
};

int N;
vector<pair<int, int>> A;
vector<int> Z;
vector<vector<int>> P;

bool check(int X) {
  vector<int> edges[140000];
  Segtree st(2 * N, edges);
  int offset = st.n - 1, V = st.V;
  for (int i = 0; i < N; i++) {
    int a = offset + P[i][0], b = offset + P[i][1];
    edges[a + V].push_back(b);
    edges[b + V].push_back(a);
  }
  for (int i = 0; i < 2 * N; i++) {
    int l = lower_bound(Z.begin(), Z.end(), Z[i] - X + 1) - Z.begin();
    int r = lower_bound(Z.begin(), Z.end(), Z[i] + X) - Z.begin() - 1;
    st.between(l, i - 1, i, edges);
    st.between(i + 1, r, i, edges);
  }
  SCC scc;
  scc.calculate(2 * V, edges);
  for (int i = 0; i < V; i++)
    if (scc.cmp[i] == scc.cmp[i + V])
      return false;
  return true;
}

int main() {
  cin >> N;
  for (int i = 0; i < N; i++) {
    int x, y;
    cin >> x >> y;
    A.emplace_back(x, i);
    A.emplace_back(y, i);
  }
  sort(A.begin(), A.end());
  P.resize(N);
  for (int i = 0; i < 2 * N; i++) {
    Z.push_back(A[i].first);
    P[A[i].second].push_back(i);
  }

  int ok = 0, ng = 1e9 + 1;
  while (ng - ok > 1) {
    int mid = (ok + ng) / 2;
    (check(mid) ? ok : ng) = mid;
  }
  cout << ok << endl;
  return 0;
}