Problem p03802 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#define _USE_MATH_DEFINES
#include <complex>
#include <functional>
#include <math.h>
using namespace std;

#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)

typedef long long ll;
const ll INF = 1e17;
const ll MOD = 998244353;
const ll MAX = 4000001;
const long double eps = 1E-14;

ll max(ll a, ll b) {
  if (a > b) {
    return a;
  }
  return b;
}

ll min(ll a, ll b) {
  if (a > b) {
    return b;
  }
  return a;
}

ll gcd(ll a, ll b) {
  if (b == 0) {
    return a;
  }
  if (a < b) {
    return gcd(b, a);
  }
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

struct edge {
  ll ind;
  ll fr;
  ll to;
  ll d;
};

class mint {
  long long x;

public:
  mint(long long x = 0) : x((x % MOD + MOD) % MOD) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint &a) {
    if ((x += a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(const mint &a) {
    if ((x += MOD - a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator*=(const mint &a) {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint operator+(const mint &a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint &a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint &a) const {
    mint res(*this);
    return res *= a;
  }

  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime MOD
  mint inv() const { return pow(MOD - 2); }
  mint &operator/=(const mint &a) { return (*this) *= a.inv(); }
  mint operator/(const mint &a) const {
    mint res(*this);
    return res /= a;
  }

  friend ostream &operator<<(ostream &os, const mint &m) {
    os << m.x;
    return os;
  }
};

mint pw(mint a, ll b) {
  if (b == 0) {
    return 1;
  }
  mint ret = pw(a, b >> 1);
  ret *= ret;
  if (b & 1) {
    ret *= a;
  }
  return ret;
}

typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;

typedef vector<mint> vmint;
typedef vector<vector<mint>> vvmint;
typedef vector<vector<vector<mint>>> vvvmint;

/////////////////////////////////////
struct SCC {
  vector<vector<edge>> g;
  ll N;
  ll M;

  vector<vector<edge>> graph; // 分解してできるグラフ
  vll ver;                    // 元のグラフとの頂点の対応
  vll ed; // 辺の対応(同じ成分に入る場合は、-頂点番号)

  vll kaeri;

  void dfs(ll v) {
    ver[v] = -1;
    for (edge e : g[v]) {
      ll w = e.to;
      if (ver[w] == -1) {
        continue;
      }
      dfs(w);
    }
    kaeri.push_back(v);
  }

  vector<vector<edge>> grev;
  void dfsrev(ll v, ll c) {
    ver[v] = c;
    for (edge e : grev[v]) {
      ll w = e.to;
      if (ver[w] != -1) {
        continue;
      }
      dfsrev(w, c);
    }
  }

  SCC(vector<vector<edge>> g0) {
    g = g0;
    N = g.size() - 1;
    M = 0;

    ver.assign(N + 1, 0);

    repn(v, N) {
      if (ver[v] == -1) {
        continue;
      }
      dfs(v);
    }

    grev.resize(N + 1);
    repn(v, N) {
      for (edge e : g[v]) {
        grev[e.to].push_back({e.ind, e.to, e.fr, e.d});
        M++;
      }
    }

    reverse(kaeri.begin(), kaeri.end());

    ll c = 0;
    for (ll v : kaeri) {
      if (ver[v] != -1) {
        continue;
      }
      c++;
      dfsrev(v, c);
    }

    ed.assign(M + 1, 0);
    ll ind = 0;
    graph.resize(c + 1);
    repn(v, N) {
      for (edge e : g[v]) {
        ll X = ver[v];
        ll Y = ver[e.to];

        if (X == Y) {
          ed[e.ind] = -X;
          continue;
        }
        ind++;
        ed[e.ind] = ind;
        graph[X].push_back({ind, X, Y, e.d});
      }
    }
  }
};

ll N;
vll x;
vll y;

vll pos;
vll verx, very;

ll H = 14;
ll M = 1 << H;

void dr(ll v, ll a, ll b, ll l, ll r, ll k, vector<vector<edge>> &g) {
  if (b <= l || a >= r) {
    return;
  }
  if (a <= l && b >= r) {
    g[v].push_back({1, v, k, 1});
    return;
  }

  dr(v, a, b, l, (l + r) / 2, 2 * k, g);
  dr(v, a, b, (l + r) / 2, r, 2 * k + 1, g);
}

bool ch(ll d) {

  vector<vector<edge>> g(2 * M);
  repn(v, M - 1) {
    g[v].push_back({1, v, 2 * v, 1});
    g[v].push_back({1, v, 2 * v + 1, 1});
  }

  rep(i, N) {
    ll v = verx[i];
    auto itr = upper_bound(pos.begin(), pos.end(), y[i] - d);
    ll a = distance(pos.begin(), itr);
    auto itr2 = lower_bound(pos.begin(), pos.end(), y[i] + d);
    ll b = distance(pos.begin(), itr2);
    dr(v + M, a, very[i], 0, M, 1, g);
    dr(v + M, very[i] + 1, b, 0, M, 1, g);
  }
  rep(i, N) {
    ll v = very[i];
    auto itr = upper_bound(pos.begin(), pos.end(), x[i] - d);
    ll a = distance(pos.begin(), itr);
    auto itr2 = lower_bound(pos.begin(), pos.end(), x[i] + d);
    ll b = distance(pos.begin(), itr2);

    dr(v + M, a, verx[i], 0, M, 1, g);
    dr(v + M, verx[i] + 1, b, 0, M, 1, g);
  }

  // repn(v, 2 * M-1) {
  //	for (edge e : g[v]) {
  //		cout << v << " " << e.to << endl;
  //	}
  // }

  SCC sc(g);

  rep(i, N) {
    if (sc.ver[verx[i] + M] == sc.ver[very[i] + M]) {
      return false;
    }
  }
  return true;
}

int main() {
  cin >> N;
  x.resize(N);
  y.resize(N);
  rep(i, N) cin >> x[i] >> y[i];

  vector<pair<ll, ll>> p(2 * N);
  rep(i, N) {
    p[i] = {x[i], i};
    p[N + i] = {y[i], N + i};
  }
  sort(p.begin(), p.end());

  pos.resize(2 * N);
  verx.resize(N);
  very.resize(N);

  rep(i, 2 * N) {
    if (p[i].second < N) {
      verx[p[i].second] = i;
    } else {
      very[p[i].second - N] = i;
    }
    pos[i] = p[i].first;
    // cout << pos[i] << endl;
  }

  ll l = 0;
  ll r = 1500000000;

  while (r - l > 1) {
    ll m = (r + l) / 2;
    if (ch(m)) {
      l = m;
    } else {
      r = m;
    }
  }
  cout << l << endl;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#define _USE_MATH_DEFINES
#include <complex>
#include <functional>
#include <math.h>
using namespace std;

#define rep(i, x) for (ll i = 0; i < x; i++)
#define repn(i, x) for (ll i = 1; i <= x; i++)

typedef long long ll;
const ll INF = 1e17;
const ll MOD = 998244353;
const ll MAX = 4000001;
const long double eps = 1E-14;

ll max(ll a, ll b) {
  if (a > b) {
    return a;
  }
  return b;
}

ll min(ll a, ll b) {
  if (a > b) {
    return b;
  }
  return a;
}

ll gcd(ll a, ll b) {
  if (b == 0) {
    return a;
  }
  if (a < b) {
    return gcd(b, a);
  }
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

struct edge {
  ll ind;
  ll fr;
  ll to;
  ll d;
};

class mint {
  long long x;

public:
  mint(long long x = 0) : x((x % MOD + MOD) % MOD) {}
  mint operator-() const { return mint(-x); }
  mint &operator+=(const mint &a) {
    if ((x += a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(const mint &a) {
    if ((x += MOD - a.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator*=(const mint &a) {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint operator+(const mint &a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint &a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint &a) const {
    mint res(*this);
    return res *= a;
  }

  mint pow(ll t) const {
    if (!t)
      return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1)
      a *= *this;
    return a;
  }

  // for prime MOD
  mint inv() const { return pow(MOD - 2); }
  mint &operator/=(const mint &a) { return (*this) *= a.inv(); }
  mint operator/(const mint &a) const {
    mint res(*this);
    return res /= a;
  }

  friend ostream &operator<<(ostream &os, const mint &m) {
    os << m.x;
    return os;
  }
};

mint pw(mint a, ll b) {
  if (b == 0) {
    return 1;
  }
  mint ret = pw(a, b >> 1);
  ret *= ret;
  if (b & 1) {
    ret *= a;
  }
  return ret;
}

typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;

typedef vector<mint> vmint;
typedef vector<vector<mint>> vvmint;
typedef vector<vector<vector<mint>>> vvvmint;

/////////////////////////////////////
struct SCC {
  vector<vector<edge>> g;
  ll N;
  ll M;

  vector<vector<edge>> graph; // 分解してできるグラフ
  vll ver;                    // 元のグラフとの頂点の対応
  vll ed; // 辺の対応(同じ成分に入る場合は、-頂点番号)

  vll kaeri;

  void dfs(ll v) {
    ver[v] = -1;
    for (edge e : g[v]) {
      ll w = e.to;
      if (ver[w] == -1) {
        continue;
      }
      dfs(w);
    }
    kaeri.push_back(v);
  }

  vector<vector<edge>> grev;
  void dfsrev(ll v, ll c) {
    ver[v] = c;
    for (edge e : grev[v]) {
      ll w = e.to;
      if (ver[w] != -1) {
        continue;
      }
      dfsrev(w, c);
    }
  }

  SCC(vector<vector<edge>> g0) {
    g = g0;
    N = g.size() - 1;
    M = 0;

    ver.assign(N + 1, 0);

    repn(v, N) {
      if (ver[v] == -1) {
        continue;
      }
      dfs(v);
    }

    grev.resize(N + 1);
    repn(v, N) {
      for (edge e : g[v]) {
        grev[e.to].push_back({e.ind, e.to, e.fr, e.d});
        M++;
      }
    }

    reverse(kaeri.begin(), kaeri.end());

    ll c = 0;
    for (ll v : kaeri) {
      if (ver[v] != -1) {
        continue;
      }
      c++;
      dfsrev(v, c);
    }

    ed.assign(M + 1, 0);
    ll ind = 0;
    graph.resize(c + 1);
    repn(v, N) {
      for (edge e : g[v]) {
        ll X = ver[v];
        ll Y = ver[e.to];

        if (X == Y) {
          ed[e.ind] = -X;
          continue;
        }
        ind++;
        ed[e.ind] = ind;
        graph[X].push_back({ind, X, Y, e.d});
      }
    }
  }
};

ll N;
vll x;
vll y;

vll pos;
vll verx, very;

ll H = 15;
ll M = 1 << H;

void dr(ll v, ll a, ll b, ll l, ll r, ll k, vector<vector<edge>> &g) {
  if (b <= l || a >= r) {
    return;
  }
  if (a <= l && b >= r) {
    g[v].push_back({1, v, k, 1});
    return;
  }

  dr(v, a, b, l, (l + r) / 2, 2 * k, g);
  dr(v, a, b, (l + r) / 2, r, 2 * k + 1, g);
}

bool ch(ll d) {

  vector<vector<edge>> g(2 * M);
  repn(v, M - 1) {
    g[v].push_back({1, v, 2 * v, 1});
    g[v].push_back({1, v, 2 * v + 1, 1});
  }

  rep(i, N) {
    ll v = verx[i];
    auto itr = upper_bound(pos.begin(), pos.end(), y[i] - d);
    ll a = distance(pos.begin(), itr);
    auto itr2 = lower_bound(pos.begin(), pos.end(), y[i] + d);
    ll b = distance(pos.begin(), itr2);
    dr(v + M, a, very[i], 0, M, 1, g);
    dr(v + M, very[i] + 1, b, 0, M, 1, g);
  }
  rep(i, N) {
    ll v = very[i];
    auto itr = upper_bound(pos.begin(), pos.end(), x[i] - d);
    ll a = distance(pos.begin(), itr);
    auto itr2 = lower_bound(pos.begin(), pos.end(), x[i] + d);
    ll b = distance(pos.begin(), itr2);

    dr(v + M, a, verx[i], 0, M, 1, g);
    dr(v + M, verx[i] + 1, b, 0, M, 1, g);
  }

  // repn(v, 2 * M-1) {
  //	for (edge e : g[v]) {
  //		cout << v << " " << e.to << endl;
  //	}
  // }

  SCC sc(g);

  rep(i, N) {
    if (sc.ver[verx[i] + M] == sc.ver[very[i] + M]) {
      return false;
    }
  }
  return true;
}

int main() {
  cin >> N;
  x.resize(N);
  y.resize(N);
  rep(i, N) cin >> x[i] >> y[i];

  vector<pair<ll, ll>> p(2 * N);
  rep(i, N) {
    p[i] = {x[i], i};
    p[N + i] = {y[i], N + i};
  }
  sort(p.begin(), p.end());

  pos.resize(2 * N);
  verx.resize(N);
  very.resize(N);

  rep(i, 2 * N) {
    if (p[i].second < N) {
      verx[p[i].second] = i;
    } else {
      very[p[i].second - N] = i;
    }
    pos[i] = p[i].first;
    // cout << pos[i] << endl;
  }

  ll l = 0;
  ll r = 1500000000;

  while (r - l > 1) {
    ll m = (r + l) / 2;
    if (ch(m)) {
      l = m;
    } else {
      r = m;
    }
  }
  cout << l << endl;
}