Problem p03802 (C++)

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

struct Node {
  int id, val;
} p[N];
struct Sgt {
  int ls, rs;
} Segt[N << 2];
struct Edge {
  int to, next;
} edge[N << 1];
int n, x, y, sgt_num, a[N], pos[N], Root;
int DFN[N], Low[N], Vis[N], Color[N];
int Stack[N], top, col_num, dfs_num;
int head[N], num_edge;
bool cmp(Node a, Node b) { return a.val < b.val; }

void add(int u, int v) {
  edge[++num_edge].to = v;
  edge[num_edge].next = head[u];
  head[u] = num_edge;
}

int Build(int l, int r) {
  if (l == r)
    return pos[((p[l].id - 1) ^ 1) + 1];
  int now = ++sgt_num;
  int mid = (l + r) >> 1;
  Segt[now].ls = Build(l, mid);
  Segt[now].rs = Build(mid + 1, r);
  add(now, Segt[now].ls);
  add(now, Segt[now].rs);
  return now;
}

void Add_Edge(int now, int l, int r, int l1, int r1, int p) {
  if (l > r1 || r < l1 || l > r)
    return;
  if (l1 <= l && r <= r1) {
    add(p, now);
    return;
  }
  int mid = (l + r) >> 1;
  Add_Edge(Segt[now].ls, l, mid, l1, r1, p);
  Add_Edge(Segt[now].rs, mid + 1, r, l1, r1, p);
}

void Clear() {
  memset(head, 0, sizeof(head));
  memset(DFN, 0, sizeof(DFN));
  memset(Low, 0, sizeof(Low));
  memset(Vis, 0, sizeof(Vis));
  col_num = dfs_num = num_edge = top = 0;
  sgt_num = 2 * n;
}

void Tarjan(int x) {
  DFN[x] = Low[x] = ++dfs_num;
  Vis[x] = 1;
  Stack[++top] = x;
  for (int i = head[x]; i; i = edge[i].next)
    if (!DFN[edge[i].to]) {
      Tarjan(edge[i].to);
      Low[x] = min(Low[x], Low[edge[i].to]);
    } else if (Vis[edge[i].to])
      Low[x] = min(Low[x], DFN[edge[i].to]);
  if (DFN[x] == Low[x]) {
    Vis[x] = 0;
    Color[x] = ++col_num;
    while (Stack[top] != x) {
      Color[Stack[top]] = col_num;
      Vis[Stack[top--]] = 0;
    }
    --top;
  }
}

bool check(int lim) {
  Clear();
  Root = Build(1, 2 * n);
  for (int i = 1; i <= 2 * n; ++i) {
    int l = upper_bound(a + 1, a + 2 * n + 1, p[i].val - lim) - a;
    int r = lower_bound(a + 1, a + 2 * n + 1, p[i].val + lim) - a - 1;
    Add_Edge(Root, 1, 2 * n, max(l, 1), i - 1, i);
    Add_Edge(Root, 1, 2 * n, i + 1, min(r, 2 * n), i);
  }
  for (int i = 1; i <= 2 * n; ++i)
    if (!DFN[i])
      Tarjan(i);
  for (int i = 1; i <= 2 * n; i += 2)
    if (Color[pos[i]] == Color[pos[i + 1]])
      return false;
  return true;
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> x >> y;
    p[i * 2 - 1] = (Node){i * 2 - 1, x};
    p[i * 2] = (Node){i * 2, y};
  }
  sort(p + 1, p + 2 * n + 1, cmp);
  for (int i = 1; i <= 2 * n; ++i)
    pos[p[i].id] = i, a[i] = p[i].val;
  int l = 0, r = 1000000000, ans = -1;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define N (500009)
using namespace std;

struct Node {
  int id, val;
} p[N];
struct Sgt {
  int ls, rs;
} Segt[N << 2];
struct Edge {
  int to, next;
} edge[N << 1];
int n, x, y, sgt_num, a[N], pos[N], Root;
int DFN[N], Low[N], Vis[N], Color[N];
int Stack[N], top, col_num, dfs_num;
int head[N], num_edge;
bool cmp(Node a, Node b) { return a.val < b.val; }

void add(int u, int v) {
  edge[++num_edge].to = v;
  edge[num_edge].next = head[u];
  head[u] = num_edge;
}

int Build(int l, int r) {
  if (l == r)
    return pos[((p[l].id - 1) ^ 1) + 1];
  int now = ++sgt_num;
  int mid = (l + r) >> 1;
  Segt[now].ls = Build(l, mid);
  Segt[now].rs = Build(mid + 1, r);
  add(now, Segt[now].ls);
  add(now, Segt[now].rs);
  return now;
}

void Add_Edge(int now, int l, int r, int l1, int r1, int p) {
  if (l > r1 || r < l1 || l > r)
    return;
  if (l1 <= l && r <= r1) {
    add(p, now);
    return;
  }
  int mid = (l + r) >> 1;
  Add_Edge(Segt[now].ls, l, mid, l1, r1, p);
  Add_Edge(Segt[now].rs, mid + 1, r, l1, r1, p);
}

void Clear() {
  memset(head, 0, sizeof(head));
  memset(DFN, 0, sizeof(DFN));
  memset(Low, 0, sizeof(Low));
  memset(Vis, 0, sizeof(Vis));
  col_num = dfs_num = num_edge = top = 0;
  sgt_num = 2 * n;
}

void Tarjan(int x) {
  DFN[x] = Low[x] = ++dfs_num;
  Vis[x] = 1;
  Stack[++top] = x;
  for (int i = head[x]; i; i = edge[i].next)
    if (!DFN[edge[i].to]) {
      Tarjan(edge[i].to);
      Low[x] = min(Low[x], Low[edge[i].to]);
    } else if (Vis[edge[i].to])
      Low[x] = min(Low[x], DFN[edge[i].to]);
  if (DFN[x] == Low[x]) {
    Vis[x] = 0;
    Color[x] = ++col_num;
    while (Stack[top] != x) {
      Color[Stack[top]] = col_num;
      Vis[Stack[top--]] = 0;
    }
    --top;
  }
}

bool check(int lim) {
  Clear();
  Root = Build(1, 2 * n);
  for (int i = 1; i <= 2 * n; ++i) {
    int l = upper_bound(a + 1, a + 2 * n + 1, p[i].val - lim) - a;
    int r = lower_bound(a + 1, a + 2 * n + 1, p[i].val + lim) - a - 1;
    Add_Edge(Root, 1, 2 * n, max(l, 1), i - 1, i);
    Add_Edge(Root, 1, 2 * n, i + 1, min(r, 2 * n), i);
  }
  for (int i = 1; i <= 2 * n; ++i)
    if (!DFN[i])
      Tarjan(i);
  for (int i = 1; i <= 2 * n; i += 2)
    if (Color[pos[i]] == Color[pos[i + 1]])
      return false;
  return true;
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    cin >> x >> y;
    p[i * 2 - 1] = (Node){i * 2 - 1, x};
    p[i * 2] = (Node){i * 2, y};
  }
  sort(p + 1, p + 2 * n + 1, cmp);
  for (int i = 1; i <= 2 * n; ++i)
    pos[p[i].id] = i, a[i] = p[i].val;
  int l = 0, r = 1000000000, ans = -1;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (check(mid))
      ans = mid, l = mid + 1;
    else
      r = mid - 1;
  }
  cout << ans << endl;
}