Problem p03802 (C++)

Buggy submission (status: Runtime Error):
// 15:40
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 20004
#define rint register int
#define lc (pos << 1)
#define rc (pos << 1 | 1)
using namespace std;

struct Node {
  int x, id;
};

inline bool cmp(const Node &x, const Node &y) { return x.x < y.x; }

int n, cnt = 0, id[N * 20][2], nid[N][2];
int tot = 0, fir[N * 20], nxt[N * 40], to[N * 40];
Node p[2][N];

inline void addEdge(const int &u, const int &v) {
  nxt[++tot] = fir[u], fir[u] = tot, to[tot] = v;
}

void Build(int l, int r, int pos, int op) {
  id[pos][op] = ++cnt;
  if (l == r) {
    nid[p[op ^ 1][l].id][op] = id[pos][op];
    return;
  }
  int mid = (l + r) >> 1;
  Build(l, mid, lc, op);
  Build(mid + 1, r, rc, op);
  addEdge(id[pos][op], id[lc][op]);
  addEdge(id[pos][op], id[rc][op]);
}

void Link(int l, int r, int L, int R, int pos, int op, int s) {
  if (L <= l && r <= R) {
    addEdge(s, id[pos][op]);
    return;
  }
  int mid = (l + r) >> 1;
  if (L <= mid)
    Link(l, mid, L, R, lc, op, s);
  if (mid < R)
    Link(mid + 1, r, L, R, rc, op, s);
}

int num[2][N];
int dfn[N], col[N * 20], stk[N * 20], top, ins[N], jsq, low[N], color;

void tarjan(int u) {
  low[u] = dfn[u] = ++jsq, stk[++top] = u, ins[u] = 1;
  for (rint i = fir[u], v; i; i = nxt[i]) {
    v = to[i];
    if (!dfn[v])
      tarjan(v), low[u] = min(low[u], low[v]);
    else if (ins[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] != low[u])
    return;
  ++color;
  while (stk[top] != u)
    col[stk[top]] = color, ins[stk[top--]] = 0;
  col[stk[top]] = color, ins[stk[top--]] = 0;
}

inline bool check(int mid) {
  tot = cnt = jsq = top = color = 0;
  memset(fir, 0, sizeof fir);
  memset(ins, 0, sizeof ins);
  memset(col, 0, sizeof col);
  memset(dfn, 0, sizeof dfn);
  memset(stk, 0, sizeof stk);
  memset(low, 0, sizeof low);
  memset(nid, 0, sizeof nid);
  memset(id, 0, sizeof id);
  Build(1, n, 1, 0);
  Build(1, n, 1, 1);
  for (rint i = 1, l, r; i <= n; ++i)
    for (rint j = 0; j <= 1; ++j)
      for (rint k = 0; k <= 1; ++k) {
        l = upper_bound(num[k] + 1, num[k] + n + 1, p[j][i].x - mid) - num[k];
        r = upper_bound(num[k] + 1, num[k] + n + 1, p[j][i].x + mid - 1) -
            num[k] - 1;
        // cout << i << " :" << j << " " << k << ": (" << l << ", " << r << ")
        // "<< p[j][i].id << " " << nid[p[j][i].id][j]<< endl;
        if (l > r)
          continue;
        if (j != k)
          Link(1, n, l, r, 1, k ^ 1, nid[p[j][i].id][j]);
        else {
          if (i > l)
            Link(1, n, l, i - 1, 1, k ^ 1, nid[p[j][i].id][j]);
          if (i < r)
            Link(1, n, i + 1, r, 1, k ^ 1, nid[p[j][i].id][j]);
        }
        //                if (l > 1) Link(1, n, 1, l - 1, 1, k,
        //                nid[p[j][i].id][j]); if (r < n) Link(1, n, r + 1, n,
        //                1, k, nid[p[j][i].id][j]);
      }
  //    for (rint i = 1; i <= cnt; ++i) {
  //        cout << i << " : ";
  //        for (rint j = fir[i]; j; j = nxt[j])
  //            cout << to[j] << " -> ";
  //        cout << endl;
  //    }
  for (rint i = 1; i <= cnt; ++i)
    if (!dfn[i])
      tarjan(i);
  //    for (rint i = 1; i <= cnt; ++i)
  //        cout << col[i] << " # ";
  //    cout << endl;
  for (rint i = 1; i <= n; ++i) {
    // cout << nid[i][0] << " "<< nid[i][1] << " " << col[nid[i][0]] << " " <<
    // col[nid[i][1]]<< endl;
    if (col[nid[i][0]] == col[nid[i][1]])
      return false;
  }
  return true;
}

int main() {
#ifdef whyqx
  freopen("work.in", "r", stdin);
  freopen("work.out", "w", stdout);
#endif
  cin >> n;
  for (rint i = 1; i <= n; ++i)
    scanf("%d%d", &p[0][i].x, &p[1][i].x), p[0][i].id = p[1][i].id = i;
  sort(p[0] + 1, p[0] + n + 1, cmp);
  sort(p[1] + 1, p[1] + n + 1, cmp);
  for (rint i = 1; i <= n; ++i)
    for (rint j = 0; j < 2; ++j)
      num[j][i] = p[j][i].x;
  //    cout << check(4) << endl;
  int l = 0, r = 1e9, res = 0;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      l = (res = mid) + 1;
    else
      r = mid - 1;
  }
  cout << res << endl;
  return 0;
}


Fixed submission:
// 15:40
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 50004
#define rint register int
#define lc (pos << 1)
#define rc (pos << 1 | 1)
using namespace std;

struct Node {
  int x, id;
};

inline bool cmp(const Node &x, const Node &y) { return x.x < y.x; }

int n, cnt = 0, id[N * 20][2], nid[N][2];
int tot = 0, fir[N * 20], nxt[N * 40], to[N * 40];
Node p[2][N];

inline void addEdge(const int &u, const int &v) {
  nxt[++tot] = fir[u], fir[u] = tot, to[tot] = v;
}

void Build(int l, int r, int pos, int op) {
  id[pos][op] = ++cnt;
  if (l == r) {
    nid[p[op ^ 1][l].id][op] = id[pos][op];
    return;
  }
  int mid = (l + r) >> 1;
  Build(l, mid, lc, op);
  Build(mid + 1, r, rc, op);
  addEdge(id[pos][op], id[lc][op]);
  addEdge(id[pos][op], id[rc][op]);
}

void Link(int l, int r, int L, int R, int pos, int op, int s) {
  if (L <= l && r <= R) {
    addEdge(s, id[pos][op]);
    return;
  }
  int mid = (l + r) >> 1;
  if (L <= mid)
    Link(l, mid, L, R, lc, op, s);
  if (mid < R)
    Link(mid + 1, r, L, R, rc, op, s);
}

int num[2][N];
int dfn[N], col[N * 20], stk[N * 20], top, ins[N], jsq, low[N], color;

void tarjan(int u) {
  low[u] = dfn[u] = ++jsq, stk[++top] = u, ins[u] = 1;
  for (rint i = fir[u], v; i; i = nxt[i]) {
    v = to[i];
    if (!dfn[v])
      tarjan(v), low[u] = min(low[u], low[v]);
    else if (ins[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (dfn[u] != low[u])
    return;
  ++color;
  while (stk[top] != u)
    col[stk[top]] = color, ins[stk[top--]] = 0;
  col[stk[top]] = color, ins[stk[top--]] = 0;
}

inline bool check(int mid) {
  tot = cnt = jsq = top = color = 0;
  memset(fir, 0, sizeof fir);
  memset(ins, 0, sizeof ins);
  memset(col, 0, sizeof col);
  memset(dfn, 0, sizeof dfn);
  memset(stk, 0, sizeof stk);
  memset(low, 0, sizeof low);
  memset(nid, 0, sizeof nid);
  memset(id, 0, sizeof id);
  Build(1, n, 1, 0);
  Build(1, n, 1, 1);
  for (rint i = 1, l, r; i <= n; ++i)
    for (rint j = 0; j <= 1; ++j)
      for (rint k = 0; k <= 1; ++k) {
        l = upper_bound(num[k] + 1, num[k] + n + 1, p[j][i].x - mid) - num[k];
        r = upper_bound(num[k] + 1, num[k] + n + 1, p[j][i].x + mid - 1) -
            num[k] - 1;
        // cout << i << " :" << j << " " << k << ": (" << l << ", " << r << ")
        // "<< p[j][i].id << " " << nid[p[j][i].id][j]<< endl;
        if (l > r)
          continue;
        if (j != k)
          Link(1, n, l, r, 1, k ^ 1, nid[p[j][i].id][j]);
        else {
          if (i > l)
            Link(1, n, l, i - 1, 1, k ^ 1, nid[p[j][i].id][j]);
          if (i < r)
            Link(1, n, i + 1, r, 1, k ^ 1, nid[p[j][i].id][j]);
        }
        //                if (l > 1) Link(1, n, 1, l - 1, 1, k,
        //                nid[p[j][i].id][j]); if (r < n) Link(1, n, r + 1, n,
        //                1, k, nid[p[j][i].id][j]);
      }
  //    for (rint i = 1; i <= cnt; ++i) {
  //        cout << i << " : ";
  //        for (rint j = fir[i]; j; j = nxt[j])
  //            cout << to[j] << " -> ";
  //        cout << endl;
  //    }
  for (rint i = 1; i <= cnt; ++i)
    if (!dfn[i])
      tarjan(i);
  //    for (rint i = 1; i <= cnt; ++i)
  //        cout << col[i] << " # ";
  //    cout << endl;
  for (rint i = 1; i <= n; ++i) {
    // cout << nid[i][0] << " "<< nid[i][1] << " " << col[nid[i][0]] << " " <<
    // col[nid[i][1]]<< endl;
    if (col[nid[i][0]] == col[nid[i][1]])
      return false;
  }
  return true;
}

int main() {
#ifdef whyqx
  freopen("work.in", "r", stdin);
  freopen("work.out", "w", stdout);
#endif
  cin >> n;
  for (rint i = 1; i <= n; ++i)
    scanf("%d%d", &p[0][i].x, &p[1][i].x), p[0][i].id = p[1][i].id = i;
  sort(p[0] + 1, p[0] + n + 1, cmp);
  sort(p[1] + 1, p[1] + n + 1, cmp);
  for (rint i = 1; i <= n; ++i)
    for (rint j = 0; j < 2; ++j)
      num[j][i] = p[j][i].x;
  //    cout << check(4) << endl;
  int l = 0, r = 1e9, res = 0;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      l = (res = mid) + 1;
    else
      r = mid - 1;
  }
  cout << res << endl;
  return 0;
}