Problem p03802 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <iostream>
#include <map>
#include <memory.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 40000;
int nodeID[2 * N];
vector<vector<int>> g;
vector<pair<int, int>> val;
int n, L;
int Not(int u) {
  if (u < L)
    return u + L;
  return u - L;
}
void addEdge(int u, int v) {
  g[Not(u)].push_back(v);
  g[Not(v)].push_back(u);
}
vector<int> S;
int comp[N], low[N], idx[N], dfs, cmp;
bool vis[N];
void DFS(int u) {
  idx[u] = low[u] = ++dfs;
  vis[u] = true;
  S.push_back(u);
  for (int i = 0; i < g[u].size(); ++i) {
    int v = g[u][i];
    if (!low[v])
      DFS(v);
    if (vis[v])
      low[u] = min(low[u], low[v]);
  }
  if (low[u] == idx[u]) {
    while (true) {
      int v = S.back();
      S.pop_back();
      vis[v] = false;
      comp[v] = cmp;
      if (u == v)
        break;
    }
    ++cmp;
  }
}
int id;
void setID(int n, int s, int e) {
  if (s == e)
    return;
  nodeID[n] = id++;
  setID(n * 2, s, (s + e) / 2);
  setID(n * 2 + 1, (s + e) / 2 + 1, e);
}
void initEdges(int n, int s, int e) {
  if (s == e) {
    nodeID[n] = val[s].second;
    return;
  }
  initEdges(n * 2, s, (s + e) / 2);
  initEdges(n * 2 + 1, (s + e) / 2 + 1, e);
  g[Not(nodeID[n])].push_back(Not(nodeID[n * 2]));
  g[Not(nodeID[n])].push_back(Not(nodeID[n * 2 + 1]));
}
int ql, qr;
void addEdges(int n, int s, int e, int u) {
  if (qr < s || ql > e)
    return;
  if (s >= ql && e <= qr) {
    g[u].push_back(Not(nodeID[n]));
    return;
  }
  addEdges(n * 2, s, (s + e) / 2, u);
  addEdges(n * 2 + 1, (s + e) / 2 + 1, e, u);
}
vector<int> sz;
bool check(int d) {
  for (int i = 0; i < g.size(); ++i)
    g[i].resize(sz[i]);
  for (int i = 1; i < val.size(); ++i) {
    ql = lower_bound(val.begin() + 1, val.end(),
                     make_pair(val[i].first - d + 1, -1)) -
         val.begin();
    if (ql < i) {
      qr = i - 1;
      addEdges(1, 1, n * 2, val[i].second);
    }
    ql = i + 1;
    qr = lower_bound(val.begin() + 1, val.end(),
                     make_pair(val[i].first + d, -1)) -
         val.begin();
    --qr;
    if (ql <= qr)
      addEdges(1, 1, n * 2, val[i].second);
  }
  memset(low, 0, sizeof(low));
  dfs = cmp = 0;
  for (int i = 0; i < g.size(); ++i)
    if (!low[i])
      DFS(i);
  for (int i = 0; i < L; ++i)
    if (comp[i] == comp[Not(i)])
      return false;
  return true;
}
int main() {
  scanf("%d", &n);
  id = n;
  setID(1, 1, n * 2);
  L = id;
  val.resize(n * 2 + 1);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &val[i].first);
    val[i].second = i - 1;
    scanf("%d", &val[i + n].first);
    val[i + n].second = Not(i - 1);
  }
  sort(val.begin() + 1, val.end());
  g.resize(L << 1);
  initEdges(1, 1, n * 2);
  for (int i = 0; i < g.size(); ++i)
    sz.push_back(g[i].size());
  int l = 0, r = 1e9, m, res = 0;
  while (l <= r) {
    m = (l + r) / 2;
    if (check(m)) {
      res = m;
      l = m + 1;
    } else
      r = m - 1;
  }
  printf("%d\n", res);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <iostream>
#include <map>
#include <memory.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 60000;
int nodeID[80000];
vector<vector<int>> g;
vector<pair<int, int>> val;
int n, L;
int Not(int u) {
  if (u < L)
    return u + L;
  return u - L;
}
void addEdge(int u, int v) {
  g[Not(u)].push_back(v);
  g[Not(v)].push_back(u);
}
vector<int> S;
int comp[N], low[N], idx[N], dfs, cmp;
bool vis[N];
void DFS(int u) {
  idx[u] = low[u] = ++dfs;
  vis[u] = true;
  S.push_back(u);
  for (int i = 0; i < g[u].size(); ++i) {
    int v = g[u][i];
    if (!low[v])
      DFS(v);
    if (vis[v])
      low[u] = min(low[u], low[v]);
  }
  if (low[u] == idx[u]) {
    while (true) {
      int v = S.back();
      S.pop_back();
      vis[v] = false;
      comp[v] = cmp;
      if (u == v)
        break;
    }
    ++cmp;
  }
}
int id;
void setID(int n, int s, int e) {
  if (s == e)
    return;
  nodeID[n] = id++;
  setID(n * 2, s, (s + e) / 2);
  setID(n * 2 + 1, (s + e) / 2 + 1, e);
}
void initEdges(int n, int s, int e) {
  if (s == e) {
    nodeID[n] = val[s].second;
    return;
  }
  initEdges(n * 2, s, (s + e) / 2);
  initEdges(n * 2 + 1, (s + e) / 2 + 1, e);
  g[Not(nodeID[n])].push_back(Not(nodeID[n * 2]));
  g[Not(nodeID[n])].push_back(Not(nodeID[n * 2 + 1]));
}
int ql, qr;
void addEdges(int n, int s, int e, int u) {
  if (qr < s || ql > e)
    return;
  if (s >= ql && e <= qr) {
    g[u].push_back(Not(nodeID[n]));
    return;
  }
  addEdges(n * 2, s, (s + e) / 2, u);
  addEdges(n * 2 + 1, (s + e) / 2 + 1, e, u);
}
vector<int> sz;
bool check(int d) {
  for (int i = 0; i < g.size(); ++i)
    g[i].resize(sz[i]);
  for (int i = 1; i < val.size(); ++i) {
    ql = lower_bound(val.begin() + 1, val.end(),
                     make_pair(val[i].first - d + 1, -1)) -
         val.begin();
    if (ql < i) {
      qr = i - 1;
      addEdges(1, 1, n * 2, val[i].second);
    }
    ql = i + 1;
    qr = lower_bound(val.begin() + 1, val.end(),
                     make_pair(val[i].first + d, -1)) -
         val.begin();
    --qr;
    if (ql <= qr)
      addEdges(1, 1, n * 2, val[i].second);
  }
  memset(low, 0, sizeof(low));
  dfs = cmp = 0;
  for (int i = 0; i < g.size(); ++i)
    if (!low[i])
      DFS(i);
  for (int i = 0; i < L; ++i)
    if (comp[i] == comp[Not(i)])
      return false;
  return true;
}
int main() {
  scanf("%d", &n);
  id = n;
  setID(1, 1, n * 2);
  L = id;
  val.resize(n * 2 + 1);
  for (int i = 1; i <= n; ++i) {
    scanf("%d", &val[i].first);
    val[i].second = i - 1;
    scanf("%d", &val[i + n].first);
    val[i + n].second = Not(i - 1);
  }
  sort(val.begin() + 1, val.end());
  g.resize(L << 1);
  initEdges(1, 1, n * 2);
  for (int i = 0; i < g.size(); ++i)
    sz.push_back(g[i].size());
  int l = 0, r = 1e9, m, res = 0;
  while (l <= r) {
    m = (l + r) / 2;
    if (check(m)) {
      res = m;
      l = m + 1;
    } else
      r = m - 1;
  }
  printf("%d\n", res);
  return 0;
}