Problem p03802 (C++)

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

const int N = 2e4 + 10, Node = N << 2;

int n, L, node, num[N << 3], tot, pos[N], x[N], y[N];

struct Edge {
  int to, next;
} way[N * 30];

struct Node {
  int v, id;
  bool operator<(const Node &A) const { return v < A.v; }
} p[N << 1];

void Add(int a, int b) {
  way[++tot] = (Edge){b, num[a]};
  num[a] = tot;
}

struct SegmentTree {
#define ls z << 1
#define rs z << 1 | 1
  int root, id[Node];

  void build(int z, int l, int r) {
    if (l == r) {
      if (p[l].id > n)
        id[z] = p[l].id - n;
      else
        id[z] = p[l].id + n;
      pos[p[l].id] = l;
      return;
    }
    int mid = (l + r) >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    id[z] = ++node;
    Add(id[z], id[ls]);
    Add(id[z], id[rs]);
  }

  void insert(int z, int l, int r, int ql, int qr, int ind) {
    if (ql <= l && r <= qr) {
      Add(ind, id[z]);
      return;
    }
    int mid = (l + r) >> 1;
    if (ql <= mid)
      insert(ls, l, mid, ql, qr, ind);
    if (qr > mid)
      insert(rs, mid + 1, r, ql, qr, ind);
  }

} st;

void Init() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x[i + 1], &y[i + 1]);
    p[i << 1].v = x[i + 1];
    p[i << 1 | 1].v = y[i + 1];
    p[i << 1].id = i + 1, p[i << 1 | 1].id = i + n + 1;
  }
}

int top, dfn[N << 3], cntdfn, que[N << 3], cntbcc, low[N << 3], col[N << 3];
bool inq[N << 3], vis[N << 3];
void Dfs(int x) {
  dfn[x] = ++cntdfn;
  low[x] = dfn[x];
  inq[x] = 1;
  vis[x] = 1;
  que[++top] = x;
  for (int i = num[x]; i; i = way[i].next) {
    int v = way[i].to;
    if (!vis[v]) {
      Dfs(v);
      low[x] = std::min(low[x], low[v]);
    } else if (inq[v])
      low[x] = std::min(low[x], dfn[v]);
  }
  if (dfn[x] == low[x]) {
    ++cntbcc;
    que[top + 1] = 0;
    while (que[top + 1] != x) {
      col[que[top]] = cntbcc;
      inq[que[top]] = 0;
      top--;
    }
  }
}

void Tarjan() {
  for (int i = 1; i <= node; ++i)
    vis[i] = 0, col[i] = 0;
  for (int i = 1; i <= node; ++i)
    if (!vis[i])
      Dfs(i);
}

int find(int a) {
  int l = 1, r = n << 1;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (p[mid].v < a)
      l = mid + 1;
    else
      r = mid - 1;
  }
  return l;
}

int put[N << 3], pt;
bool Check(int ans) {
  tot = pt;
  for (int i = 1; i <= node; ++i)
    num[i] = put[i];
  int l, r;
  for (int i = 1; i <= n; ++i) {
    l = find(x[i] - ans + 1);
    r = find(x[i] + ans) - 1;
    if (l <= r) {
      if (pos[i] > l)
        st.insert(st.root, 1, L, l, pos[i] - 1, i);
      if (pos[i] < r)
        st.insert(st.root, 1, L, pos[i] + 1, r, i);
    }
    l = find(y[i] - ans + 1);
    r = find(y[i] + ans) - 1;
    if (l <= r) {
      if (pos[i + n] > l)
        st.insert(st.root, 1, L, l, pos[i + n] - 1, i + n);
      if (pos[i + n] < r)
        st.insert(st.root, 1, L, pos[i + n] + 1, r, i + n);
    }
  }
  Tarjan();
  for (int i = 1; i <= n; ++i)
    if (col[i] == col[i + n])
      return 0;
  return 1;
}

void Solve() {
  L = n << 1;
  std::sort(p, p + 2 * n);
  for (int i = 2 * n; i >= 1; --i)
    p[i] = p[i - 1];
  st.root = 1;
  node = 2 * n;
  st.build(st.root, 1, L);
  for (int i = 1; i <= node; ++i)
    put[i] = num[i];
  pt = tot;
  int l = 1, r = 1e9;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (Check(mid))
      l = mid + 1;
    else
      r = mid - 1;
  }
  printf("%d\n", r);
}

int main() {
  Init();
  Solve();
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

const int N = 2e4 + 10, Node = N << 2;

int n, L, node, num[N << 3], tot, pos[N], x[N], y[N];

struct Edge {
  int to, next;
} way[N * 100];

struct Node {
  int v, id;
  bool operator<(const Node &A) const { return v < A.v; }
} p[N << 1];

void Add(int a, int b) {
  way[++tot] = (Edge){b, num[a]};
  num[a] = tot;
}

struct SegmentTree {
#define ls z << 1
#define rs z << 1 | 1
  int root, id[Node];

  void build(int z, int l, int r) {
    if (l == r) {
      if (p[l].id > n)
        id[z] = p[l].id - n;
      else
        id[z] = p[l].id + n;
      pos[p[l].id] = l;
      return;
    }
    int mid = (l + r) >> 1;
    build(ls, l, mid);
    build(rs, mid + 1, r);
    id[z] = ++node;
    Add(id[z], id[ls]);
    Add(id[z], id[rs]);
  }

  void insert(int z, int l, int r, int ql, int qr, int ind) {
    if (ql <= l && r <= qr) {
      Add(ind, id[z]);
      return;
    }
    int mid = (l + r) >> 1;
    if (ql <= mid)
      insert(ls, l, mid, ql, qr, ind);
    if (qr > mid)
      insert(rs, mid + 1, r, ql, qr, ind);
  }

} st;

void Init() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d%d", &x[i + 1], &y[i + 1]);
    p[i << 1].v = x[i + 1];
    p[i << 1 | 1].v = y[i + 1];
    p[i << 1].id = i + 1, p[i << 1 | 1].id = i + n + 1;
  }
}

int top, dfn[N << 3], cntdfn, que[N << 3], cntbcc, low[N << 3], col[N << 3];
bool inq[N << 3], vis[N << 3];
void Dfs(int x) {
  dfn[x] = ++cntdfn;
  low[x] = dfn[x];
  inq[x] = 1;
  vis[x] = 1;
  que[++top] = x;
  for (int i = num[x]; i; i = way[i].next) {
    int v = way[i].to;
    if (!vis[v]) {
      Dfs(v);
      low[x] = std::min(low[x], low[v]);
    } else if (inq[v])
      low[x] = std::min(low[x], dfn[v]);
  }
  if (dfn[x] == low[x]) {
    ++cntbcc;
    que[top + 1] = 0;
    while (que[top + 1] != x) {
      col[que[top]] = cntbcc;
      inq[que[top]] = 0;
      top--;
    }
  }
}

void Tarjan() {
  for (int i = 1; i <= node; ++i)
    vis[i] = 0, col[i] = 0;
  for (int i = 1; i <= node; ++i)
    if (!vis[i])
      Dfs(i);
}

int find(int a) {
  int l = 1, r = n << 1;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (p[mid].v < a)
      l = mid + 1;
    else
      r = mid - 1;
  }
  return l;
}

int put[N << 3], pt;
bool Check(int ans) {
  tot = pt;
  for (int i = 1; i <= node; ++i)
    num[i] = put[i];
  int l, r;
  for (int i = 1; i <= n; ++i) {
    l = find(x[i] - ans + 1);
    r = find(x[i] + ans) - 1;
    if (l <= r) {
      if (pos[i] > l)
        st.insert(st.root, 1, L, l, pos[i] - 1, i);
      if (pos[i] < r)
        st.insert(st.root, 1, L, pos[i] + 1, r, i);
    }
    l = find(y[i] - ans + 1);
    r = find(y[i] + ans) - 1;
    if (l <= r) {
      if (pos[i + n] > l)
        st.insert(st.root, 1, L, l, pos[i + n] - 1, i + n);
      if (pos[i + n] < r)
        st.insert(st.root, 1, L, pos[i + n] + 1, r, i + n);
    }
  }
  Tarjan();
  for (int i = 1; i <= n; ++i)
    if (col[i] == col[i + n])
      return 0;
  return 1;
}

void Solve() {
  L = n << 1;
  std::sort(p, p + 2 * n);
  for (int i = 2 * n; i >= 1; --i)
    p[i] = p[i - 1];
  st.root = 1;
  node = 2 * n;
  st.build(st.root, 1, L);
  for (int i = 1; i <= node; ++i)
    put[i] = num[i];
  pt = tot;
  int l = 1, r = 1e9;
  while (l <= r) {
    int mid = (l + r) >> 1;
    if (Check(mid))
      l = mid + 1;
    else
      r = mid - 1;
  }
  printf("%d\n", r);
}

int main() {
  Init();
  Solve();
  return 0;
}