Problem p03802 (C++)

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

typedef long long ll;
#define REP(i, n) for (int i = 0, _n = (int)(n); i < _n; ++i)
#define ALL(v) (v).begin(), (v).end()
#define CLR(t, v) memset(t, (v), sizeof(t))
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  return os << "(" << a.first << "," << a.second << ")";
}
template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << (*i) << " ";
  cout << endl;
}
template <class T> void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <class T> void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}

int nextInt() {
  int x;
  scanf("%d", &x);
  return x;
}

const int MAX_N = 81234;
vector<int> g[MAX_N], r[MAX_N];
void clear_edge() {
  REP(i, MAX_N) g[i].clear();
  REP(i, MAX_N) r[i].clear();
}
int vid(int id, int tf) { return 2 * id + tf; }
void add_edge(int a, int b) {
  // cout << "(" << a/2 << "," << a%2 << ")" << "->" << "("<<b/2 << "," << b%2
  // <<")" << endl;
  g[a].push_back(b);
  r[b].push_back(a);
}

int sccid[MAX_N];
int sccnum;
void dfs(int p, vector<int> &order) {
  if (sccid[p] != 0)
    return;
  sccid[p] = 1;
  for (int i : g[p])
    dfs(i, order);
  order.push_back(p);
}
void rdfs(int p, int id) {
  if (sccid[p] != -1)
    return;
  sccid[p] = id;
  for (int i : r[p])
    rdfs(i, id);
}
void scc(int N) {
  vector<int> order;
  CLR(sccid, 0);
  REP(i, N) dfs(i, order);
  CLR(sccid, -1);
  sccnum = 0;
  for (int i = (int)order.size() - 1; i >= 0; i--)
    if (sccid[order[i]] == -1) {
      rdfs(order[i], sccnum);
      sccnum++;
    }
}

void cover(int node, int a, int b, const int L, const int R, const int p) {
  if (R - L <= 0)
    return;
  if (L <= a && b <= R) {
    // ~(x AND y) <=> (~x OR ~y) <=> (x -> ~y) <=> (y -> ~x)
    add_edge(vid(node, 1), vid(p, 0));
    add_edge(vid(p, 1), vid(node, 0));
    return;
  }
  if (b <= L || R <= a)
    return;
  if (b - a <= 1)
    return;
  cover(node * 2, a, (a + b) / 2, L, R, p);
  cover(node * 2 + 1, (a + b) / 2, b, L, R, p);
}

// 距離がD以上はなれていればOK
bool possible(vector<pair<int, int>> z, vector<pair<int, int>> is, int D) {
  const int INF = 1001001001;
  clear_edge();

  int NN = (int)z.size();
  int K = 1;
  while (K < NN)
    K *= 2;

  for (int k = 2; k < K; k++) {
    add_edge(vid(k, 1), vid(k / 2, 1));
  }
  REP(i, NN) { add_edge(vid(K + i, 1), vid((K + i) / 2, 1)); }

  REP(i, is.size()) {
    // ~(x AND y) <=> (~x OR ~y) <=> (x -> ~y) <=> (y -> ~x)
    add_edge(vid(K + is[i].first, 1), vid(K + is[i].second, 0));
    add_edge(vid(K + is[i].second, 1), vid(K + is[i].first, 0));

    // ~(~x AND ~y) <=> (x OR y) <=> (~x -> y) <=> (~y -> x)
    add_edge(vid(K + is[i].first, 0), vid(K + is[i].second, 1));
    add_edge(vid(K + is[i].second, 0), vid(K + is[i].first, 1));
  }

  // 距離 D より小さい点が同時に 1 を禁止
  REP(i, NN) {
    int pivot = z[i].first;
    int L = distance(z.begin(), upper_bound(ALL(z), make_pair(pivot - D, INF)));
    int R =
        distance(z.begin(), lower_bound(ALL(z), make_pair(pivot + D, -INF)));
    // [L, R) の範囲が禁止。
    cover(1, 0, K, L, i, K + i);
    cover(1, 0, K, i + 1, R, K + i);
  }

  scc((K + NN) * 2);
  // pv(sccid, sccid + (K+NN)*2);
  for (int i = 0; i < (K + NN) * 2; i += 2) {
    if (sccid[i] == sccid[i + 1])
      return false;
  }
  return true;
}

int main2() {
  int N = nextInt();
  vector<int> x(N), y(N);
  REP(i, N) {
    x[i] = nextInt();
    y[i] = nextInt();
  }
  vector<pair<int, int>> z, is;
  REP(i, N) {
    z.push_back({x[i], 2 * i});
    z.push_back({y[i], 2 * i + 1});
  }
  sort(ALL(z));

  REP(i, N) {
    int a = distance(z.begin(), lower_bound(ALL(z), make_pair(x[i], 2 * i)));
    int b =
        distance(z.begin(), lower_bound(ALL(z), make_pair(y[i], 2 * i + 1)));
    is.push_back({a, b});
  }

  int lo = 0;
  int hi = 1001001001;
  while (hi - lo > 1) {
    int mid = (hi + lo) / 2;
    if (possible(z, is, mid))
      lo = mid;
    else
      hi = mid;
  }
  cout << lo << endl;
  return 0;
}

int main() {
  for (; !cin.eof(); cin >> ws)
    main2();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i, n) for (int i = 0, _n = (int)(n); i < _n; ++i)
#define ALL(v) (v).begin(), (v).end()
#define CLR(t, v) memset(t, (v), sizeof(t))
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
  return os << "(" << a.first << "," << a.second << ")";
}
template <class T> void pv(T a, T b) {
  for (T i = a; i != b; ++i)
    cout << (*i) << " ";
  cout << endl;
}
template <class T> void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}
template <class T> void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}

int nextInt() {
  int x;
  scanf("%d", &x);
  return x;
}

const int MAX_N = 105536;
vector<int> g[MAX_N], r[MAX_N];
void clear_edge() {
  REP(i, MAX_N) g[i].clear();
  REP(i, MAX_N) r[i].clear();
}
int vid(int id, int tf) { return 2 * id + tf; }
void add_edge(int a, int b) {
  // cout << "(" << a/2 << "," << a%2 << ")" << "->" << "("<<b/2 << "," << b%2
  // <<")" << endl;
  g[a].push_back(b);
  r[b].push_back(a);
}

int sccid[MAX_N];
int sccnum;
void dfs(int p, vector<int> &order) {
  if (sccid[p] != 0)
    return;
  sccid[p] = 1;
  for (int i : g[p])
    dfs(i, order);
  order.push_back(p);
}
void rdfs(int p, int id) {
  if (sccid[p] != -1)
    return;
  sccid[p] = id;
  for (int i : r[p])
    rdfs(i, id);
}
void scc(int N) {
  vector<int> order;
  CLR(sccid, 0);
  REP(i, N) dfs(i, order);
  CLR(sccid, -1);
  sccnum = 0;
  for (int i = (int)order.size() - 1; i >= 0; i--)
    if (sccid[order[i]] == -1) {
      rdfs(order[i], sccnum);
      sccnum++;
    }
}

void cover(int node, int a, int b, const int L, const int R, const int p) {
  if (R - L <= 0)
    return;
  if (L <= a && b <= R) {
    // ~(x AND y) <=> (~x OR ~y) <=> (x -> ~y) <=> (y -> ~x)
    add_edge(vid(node, 1), vid(p, 0));
    add_edge(vid(p, 1), vid(node, 0));
    return;
  }
  if (b <= L || R <= a)
    return;
  if (b - a <= 1)
    return;
  cover(node * 2, a, (a + b) / 2, L, R, p);
  cover(node * 2 + 1, (a + b) / 2, b, L, R, p);
}

// 距離がD以上はなれていればOK
bool possible(vector<pair<int, int>> z, vector<pair<int, int>> is, int D) {
  const int INF = 1001001001;
  clear_edge();

  int NN = (int)z.size();
  int K = 1;
  while (K < NN)
    K *= 2;

  for (int k = 2; k < K; k++) {
    add_edge(vid(k, 1), vid(k / 2, 1));
  }
  REP(i, NN) { add_edge(vid(K + i, 1), vid((K + i) / 2, 1)); }

  REP(i, is.size()) {
    // ~(x AND y) <=> (~x OR ~y) <=> (x -> ~y) <=> (y -> ~x)
    add_edge(vid(K + is[i].first, 1), vid(K + is[i].second, 0));
    add_edge(vid(K + is[i].second, 1), vid(K + is[i].first, 0));

    // ~(~x AND ~y) <=> (x OR y) <=> (~x -> y) <=> (~y -> x)
    add_edge(vid(K + is[i].first, 0), vid(K + is[i].second, 1));
    add_edge(vid(K + is[i].second, 0), vid(K + is[i].first, 1));
  }

  // 距離 D より小さい点が同時に 1 を禁止
  REP(i, NN) {
    int pivot = z[i].first;
    int L = distance(z.begin(), upper_bound(ALL(z), make_pair(pivot - D, INF)));
    int R =
        distance(z.begin(), lower_bound(ALL(z), make_pair(pivot + D, -INF)));
    // [L, R) の範囲が禁止。
    cover(1, 0, K, L, i, K + i);
    cover(1, 0, K, i + 1, R, K + i);
  }

  scc((K + NN) * 2);
  // pv(sccid, sccid + (K+NN)*2);
  for (int i = 0; i < (K + NN) * 2; i += 2) {
    if (sccid[i] == sccid[i + 1])
      return false;
  }
  return true;
}

int main2() {
  int N = nextInt();
  vector<int> x(N), y(N);
  REP(i, N) {
    x[i] = nextInt();
    y[i] = nextInt();
  }
  vector<pair<int, int>> z, is;
  REP(i, N) {
    z.push_back({x[i], 2 * i});
    z.push_back({y[i], 2 * i + 1});
  }
  sort(ALL(z));

  REP(i, N) {
    int a = distance(z.begin(), lower_bound(ALL(z), make_pair(x[i], 2 * i)));
    int b =
        distance(z.begin(), lower_bound(ALL(z), make_pair(y[i], 2 * i + 1)));
    is.push_back({a, b});
  }

  int lo = 0;
  int hi = 1001001001;
  while (hi - lo > 1) {
    int mid = (hi + lo) / 2;
    if (possible(z, is, mid))
      lo = mid;
    else
      hi = mid;
  }
  cout << lo << endl;
  return 0;
}

int main() {
  for (; !cin.eof(); cin >> ws)
    main2();
  return 0;
}