Problem p03802 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 40020
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = (x << 3) + (x << 1) + c - '0';
    c = getchar();
  }
  return x * f;
}
int n, X[N], Y[N], b[N], x[N], y[N], to[N], pos[N], l, r, ans, a[N], gu[N];
int cnt, head[N];
bool cmp(int i, int j) { return a[i] < a[j]; }
struct Edge {
  int to, nxt;
} edge[N << 5];
void add(int a, int b) {
  ++cnt;
  edge[cnt].to = b;
  edge[cnt].nxt = head[a];
  head[a] = cnt;
}
int segtot, seg[N];
struct node {
  int l, r;
} tree[N << 2];
#define ls i << 1
#define rs i << 1 | 1
void build(int i, int l, int r) {
  tree[i].l = l;
  tree[i].r = r;
  seg[i] = ++segtot;
  if (l == r) {
    add(seg[i], ((pos[l] + n - 1) % (2 * n) + 1));
    return;
  }
  int mid = (l + r) >> 1;
  build(ls, l, mid);
  build(rs, mid + 1, r);
  add(seg[i], seg[ls]);
  add(seg[i], seg[rs]);
}
int low[N], dfn[N], num, tot, col[N], vis[N];
stack<int> st;
void Tarjan(int u) {
  low[u] = dfn[u] = ++num;
  st.push(u);
  vis[u] = 1;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (!dfn[v]) {
      Tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (vis[v]) {
      low[u] = min(low[u], dfn[v]);
    }
  }
  if (low[u] == dfn[u]) {
    int t = 0;
    ++tot;
    while (u ^ t) {
      t = st.top();
      st.pop();
      vis[t] = 0;
      col[t] = tot;
    }
  }
}
void Change(int i, int l, int r, int u) {
  if (l > r)
    return;
  if (tree[i].l >= l && tree[i].r <= r) {
    add(u, seg[i]);
    return;
  }
  int mid = (tree[i].l + tree[i].r) >> 1;
  if (l <= mid) {
    Change(ls, l, r, u);
  }
  if (r > mid) {
    Change(rs, l, r, u);
  }
}
bool check(int d) {
  memset(head, 0, sizeof(head));
  memset(dfn, 0, sizeof(dfn));
  memset(col, 0, sizeof(col));
  memset(low, 0, sizeof(low));
  cnt = tot = num = 0;
  segtot = (n << 1);
  build(1, 1, n << 1);
  for (int i = 1; i <= (n << 1); ++i) {
    int l = upper_bound(b + 1, b + (n << 1) + 1, a[i] - d) - b;
    int r = lower_bound(b + 1, b + (n << 1) + 1, a[i] + d) - b - 1;
    Change(1, l, gu[i] - 1, i);
    Change(1, gu[i] + 1, r, i);
  }
  for (int i = 1; i <= segtot; ++i) {
    if (!dfn[i])
      Tarjan(i);
  }
  for (int i = 1; i <= n; ++i) {
    if (col[i] == col[i + n])
      return false;
  }
  return true;
}
int main() {
  n = read();
  for (int i = 1; i <= n; ++i) {
    X[i] = a[i] = read(), Y[i] = a[i + n] = read();
  }
  for (int i = 1; i <= (n << 1); ++i) {
    pos[i] = i;
    b[i] = a[i];
  }
  sort(b + 1, b + (n << 1) + 1);
  sort(pos + 1, pos + (n << 1) + 1, cmp);
  for (int i = 1; i <= (n << 1); ++i) {
    gu[pos[i]] = i;
  }
  l = 0, r = 1e9 + 1;
  while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
      ans = mid, l = mid + 1;
    } else {
      r = mid;
    }
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 80020
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = (x << 3) + (x << 1) + c - '0';
    c = getchar();
  }
  return x * f;
}
int n, X[N], Y[N], b[N], x[N], y[N], to[N], pos[N], l, r, ans, a[N], gu[N];
int cnt, head[N];
bool cmp(int i, int j) { return a[i] < a[j]; }
struct Edge {
  int to, nxt;
} edge[N << 5];
void add(int a, int b) {
  ++cnt;
  edge[cnt].to = b;
  edge[cnt].nxt = head[a];
  head[a] = cnt;
}
int segtot, seg[N];
struct node {
  int l, r;
} tree[N << 2];
#define ls i << 1
#define rs i << 1 | 1
void build(int i, int l, int r) {
  tree[i].l = l;
  tree[i].r = r;
  seg[i] = ++segtot;
  if (l == r) {
    add(seg[i], ((pos[l] + n - 1) % (2 * n) + 1));
    return;
  }
  int mid = (l + r) >> 1;
  build(ls, l, mid);
  build(rs, mid + 1, r);
  add(seg[i], seg[ls]);
  add(seg[i], seg[rs]);
}
int low[N], dfn[N], num, tot, col[N], vis[N];
stack<int> st;
void Tarjan(int u) {
  low[u] = dfn[u] = ++num;
  st.push(u);
  vis[u] = 1;
  for (int i = head[u]; i; i = edge[i].nxt) {
    int v = edge[i].to;
    if (!dfn[v]) {
      Tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (vis[v]) {
      low[u] = min(low[u], dfn[v]);
    }
  }
  if (low[u] == dfn[u]) {
    int t = 0;
    ++tot;
    while (u ^ t) {
      t = st.top();
      st.pop();
      vis[t] = 0;
      col[t] = tot;
    }
  }
}
void Change(int i, int l, int r, int u) {
  if (l > r)
    return;
  if (tree[i].l >= l && tree[i].r <= r) {
    add(u, seg[i]);
    return;
  }
  int mid = (tree[i].l + tree[i].r) >> 1;
  if (l <= mid) {
    Change(ls, l, r, u);
  }
  if (r > mid) {
    Change(rs, l, r, u);
  }
}
bool check(int d) {
  memset(head, 0, sizeof(head));
  memset(dfn, 0, sizeof(dfn));
  memset(col, 0, sizeof(col));
  memset(low, 0, sizeof(low));
  cnt = tot = num = 0;
  segtot = (n << 1);
  build(1, 1, n << 1);
  for (int i = 1; i <= (n << 1); ++i) {
    int l = upper_bound(b + 1, b + (n << 1) + 1, a[i] - d) - b;
    int r = lower_bound(b + 1, b + (n << 1) + 1, a[i] + d) - b - 1;
    Change(1, l, gu[i] - 1, i);
    Change(1, gu[i] + 1, r, i);
  }
  for (int i = 1; i <= segtot; ++i) {
    if (!dfn[i])
      Tarjan(i);
  }
  for (int i = 1; i <= n; ++i) {
    if (col[i] == col[i + n])
      return false;
  }
  return true;
}
int main() {
  n = read();
  for (int i = 1; i <= n; ++i) {
    X[i] = a[i] = read(), Y[i] = a[i + n] = read();
  }
  for (int i = 1; i <= (n << 1); ++i) {
    pos[i] = i;
    b[i] = a[i];
  }
  sort(b + 1, b + (n << 1) + 1);
  sort(pos + 1, pos + (n << 1) + 1, cmp);
  for (int i = 1; i <= (n << 1); ++i) {
    gu[pos[i]] = i;
  }
  l = 0, r = 1e9 + 1;
  while (l < r) {
    int mid = (l + r) >> 1;
    if (check(mid)) {
      ans = mid, l = mid + 1;
    } else {
      r = mid;
    }
  }
  printf("%d\n", ans);
  return 0;
}