Problem p03802 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
#define RI register int
const int MAXN = 2000000;
const int MAXM = 10000000;
const int MX = 1000000000;
int n, a[MAXN + 10], b[MAXN + 10], p[2][MAXN + 10], lp, lop;
int lc[MAXN + 10], rc[MAXN + 10], sz = 1;
vector<int> ch[MAXN + 10];
int fir[MAXN + 10], nxt[MAXM + 10], to[MAXM + 10], tote;
int dfn[MAXN + 10], low[MAXN + 10], dfstime, in[MAXN + 10], cnt, S[MAXN + 10],
    top;
bool inS[MAXN + 10];
void dfs(int u) {
  dfn[u] = low[u] = ++dfstime;
  S[++top] = u;
  inS[u] = true;
  for (RI i = fir[u], v; v = to[i], i; i = nxt[i]) {
    if (!dfn[v])
      dfs(v), low[u] = min(low[u], low[v]);
    else if (inS[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    ++cnt;
    int now = -1;
    while (now != u) {
      now = S[top--];
      inS[now] = false;
      in[now] = cnt;
    }
  }
}
inline void adde(int u, int v) {
  to[++tote] = v;
  nxt[tote] = fir[u];
  fir[u] = tote;
}
void initlinker(int o) {
  if (lc[o])
    adde(o, lc[o]), initlinker(lc[o]);
  if (rc[o])
    adde(o, rc[o]), initlinker(rc[o]);
  for (int i = 0; i < (int)ch[o].size(); ++i)
    adde(o, ch[o][i]);
}
void link(int ql, int qr, int o = 1, int l = 1, int r = MX) {
  if (!o)
    return;
  if (ql == l && qr == r) {
    if ((*lower_bound(ch[o].begin(), ch[o].end(), lop)) != lop) {
      adde(lp, o);
      return;
    } else if (l == r)
      for (RI i = 0; i < (int)ch[o].size(); ++i)
        if (ch[o][i] != lop)
          adde(lp, ch[o][i]);
  }
  int mid = (l + r) >> 1;
  if (qr <= mid)
    link(ql, qr, lc[o], l, mid);
  else if (ql > mid)
    link(ql, qr, rc[o], mid + 1, r);
  else
    link(ql, mid, lc[o], l, mid), link(mid + 1, qr, rc[o], mid + 1, r);
}
inline bool check(int w) {
  if (w == 0)
    return true;
  for (RI i = 1; i <= sz; ++i)
    fir[i] = dfn[i] = 0;
  dfstime = cnt = tote = 0;
  initlinker(1);
  for (int i = 1; i <= n; ++i) {
    lp = p[0][i];
    lop = p[1][i];
    link(max(1, a[i] - w + 1), min(MX, a[i] + w - 1));
    swap(lp, lop);
    link(max(1, b[i] - w + 1), min(MX, b[i] + w - 1));
  }
  for (int i = 1; i <= sz; ++i)
    if (!dfn[i])
      dfs(i);
  for (int i = 1; i <= n; ++i)
    if (in[p[0][i]] == in[p[1][i]])
      return false;
  return true;
}
void insert(int &p, int q, int o = 1, int l = 1, int r = MX) {
  if (l == r) {
    ch[o].push_back(p = ++sz);
    return;
  }
  int mid = (l + r) >> 1;
  if (q <= mid)
    insert(p, q, (lc[o] ? lc[o] : (lc[o] = ++sz)), l, mid);
  else
    insert(p, q, (rc[o] ? rc[o] : (rc[o] = ++sz)), mid + 1, r);
  ch[o].push_back(p);
}
int read() {
  int res;
  char ch;
  while (!isdigit(ch = getchar()))
    ;
  res = ch - '0';
  while (isdigit(ch = getchar()))
    res = res * 10 - '0' + ch;
  return res;
}
int main() {
  n = read();
  for (RI i = 1; i <= n; ++i) {
    a[i] = read();
    b[i] = read();
    insert(p[0][i], b[i]);
    insert(p[1][i], a[i]);
  }
  for (RI i = 1; i <= sz; ++i)
    sort(ch[i].begin(), ch[i].end());
  int left = 0, mid, right = MX, ans = 0;
  while (left <= right) {
    mid = (left + right) >> 1;
    if (check(mid)) {
      ans = mid;
      left = mid + 1;
    } else
      right = mid - 1;
  }
  printf("%d", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
#define RI register int
const int MAXN = 2000000;
const int MAXM = 20000000;
const int MX = 1000000000;
int n, a[MAXN + 10], b[MAXN + 10], p[2][MAXN + 10], lp, lop;
int lc[MAXN + 10], rc[MAXN + 10], sz = 1;
vector<int> ch[MAXN + 10];
int fir[MAXN + 10], nxt[MAXM + 10], to[MAXM + 10], tote;
int dfn[MAXN + 10], low[MAXN + 10], dfstime, in[MAXN + 10], cnt, S[MAXN + 10],
    top;
bool inS[MAXN + 10];
void dfs(int u) {
  dfn[u] = low[u] = ++dfstime;
  S[++top] = u;
  inS[u] = true;
  for (RI i = fir[u], v; v = to[i], i; i = nxt[i]) {
    if (!dfn[v])
      dfs(v), low[u] = min(low[u], low[v]);
    else if (inS[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] == low[u]) {
    ++cnt;
    int now = -1;
    while (now != u) {
      now = S[top--];
      inS[now] = false;
      in[now] = cnt;
    }
  }
}
inline void adde(int u, int v) {
  to[++tote] = v;
  nxt[tote] = fir[u];
  fir[u] = tote;
}
void initlinker(int o) {
  if (lc[o])
    adde(o, lc[o]), initlinker(lc[o]);
  if (rc[o])
    adde(o, rc[o]), initlinker(rc[o]);
  for (int i = 0; i < (int)ch[o].size(); ++i)
    adde(o, ch[o][i]);
}
void link(int ql, int qr, int o = 1, int l = 1, int r = MX) {
  if (!o)
    return;
  if (ql == l && qr == r) {
    if ((*lower_bound(ch[o].begin(), ch[o].end(), lop)) != lop) {
      adde(lp, o);
      return;
    } else if (l == r)
      for (RI i = 0; i < (int)ch[o].size(); ++i)
        if (ch[o][i] != lop)
          adde(lp, ch[o][i]);
  }
  int mid = (l + r) >> 1;
  if (qr <= mid)
    link(ql, qr, lc[o], l, mid);
  else if (ql > mid)
    link(ql, qr, rc[o], mid + 1, r);
  else
    link(ql, mid, lc[o], l, mid), link(mid + 1, qr, rc[o], mid + 1, r);
}
inline bool check(int w) {
  if (w == 0)
    return true;
  for (RI i = 1; i <= sz; ++i)
    fir[i] = dfn[i] = 0;
  dfstime = cnt = tote = 0;
  initlinker(1);
  for (int i = 1; i <= n; ++i) {
    lp = p[0][i];
    lop = p[1][i];
    link(max(1, a[i] - w + 1), min(MX, a[i] + w - 1));
    swap(lp, lop);
    link(max(1, b[i] - w + 1), min(MX, b[i] + w - 1));
  }
  for (int i = 1; i <= sz; ++i)
    if (!dfn[i])
      dfs(i);
  for (int i = 1; i <= n; ++i)
    if (in[p[0][i]] == in[p[1][i]])
      return false;
  return true;
}
void insert(int &p, int q, int o = 1, int l = 1, int r = MX) {
  if (l == r) {
    ch[o].push_back(p = ++sz);
    return;
  }
  int mid = (l + r) >> 1;
  if (q <= mid)
    insert(p, q, (lc[o] ? lc[o] : (lc[o] = ++sz)), l, mid);
  else
    insert(p, q, (rc[o] ? rc[o] : (rc[o] = ++sz)), mid + 1, r);
  ch[o].push_back(p);
}
int read() {
  int res;
  char ch;
  while (!isdigit(ch = getchar()))
    ;
  res = ch - '0';
  while (isdigit(ch = getchar()))
    res = res * 10 - '0' + ch;
  return res;
}
int main() {
  n = read();
  for (RI i = 1; i <= n; ++i) {
    a[i] = read();
    b[i] = read();
    insert(p[0][i], b[i]);
    insert(p[1][i], a[i]);
  }
  for (RI i = 1; i <= sz; ++i)
    sort(ch[i].begin(), ch[i].end());
  int left = 0, mid, right = MX, ans = 0;
  while (left <= right) {
    mid = (left + right) >> 1;
    if (check(mid)) {
      ans = mid;
      left = mid + 1;
    } else
      right = mid - 1;
  }
  printf("%d", ans);
  return 0;
}