Problem p03802 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>

using namespace std;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch))
    f = ch == '-' ? -1 : f, ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}

const int N = 10005;
const int LGN = 15;
const int S = N << 3;
const int V = S + (N << 1);
const int E = V + ((N << 2) * LGN);

struct data {
  int key, id;
  bool tp;

  bool operator<(data const d) const {
    return key < d.key || key == d.key && id < d.id;
  }
} srt[N << 1];

int last[V], DFN[V], low[V], bid[V];
int nxt[E], tov[E];
int x[N], y[N];
bool exist[V];
int id[N << 1];
int n, tot, ans, idx, bcnt;

stack<int> st;

inline void insert(int x, int y) {
  tov[++tot] = y, nxt[tot] = last[x], last[x] = tot;
}

void build(int x, int l, int r) {
  if (l == r) {
    id[l] = x;
    return;
  }
  int mid = l + r >> 1;
  build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r),
      insert(x + n * 2, (x << 1) + n * 2),
      insert(x + n * 2, (x << 1 | 1) + n * 2);
}

void addedge(int x, int st, int en, int l, int r, int p) {
  if (st == l && en == r) {
    insert(p, x + n * 2);
    return;
  }
  int mid = l + r >> 1;
  if (en <= mid)
    addedge(x << 1, st, en, l, mid, p);
  else if (mid + 1 <= st)
    addedge(x << 1 | 1, st, en, mid + 1, r, p);
  else
    addedge(x << 1, st, mid, l, mid, p),
        addedge(x << 1 | 1, mid + 1, en, mid + 1, r, p);
}

void tarjan(int x) {
  DFN[x] = low[x] = ++idx, st.push(x), exist[x] = 1;
  for (int i = last[x], y; i; i = nxt[i])
    if (!DFN[y = tov[i]])
      tarjan(y), low[x] = min(low[x], low[y]);
    else if (exist[y])
      low[x] = min(low[x], DFN[y]);
  if (DFN[x] == low[x]) {
    int y;
    ++bcnt;
    do {
      exist[y = st.top()] = 0, st.pop(), bid[y] = bcnt;
    } while (x != y);
  }
}

bool judge(int dis) {
  --dis, memset(last, 0, sizeof last), memset(tov, 0, sizeof tov),
      memset(nxt, 0, sizeof nxt), tot = 0;
  build(1, 1, n << 1);
  for (int i = 1; i <= n << 1; ++i)
    if (srt[i].tp)
      insert(id[i] + n * 2, srt[i].id * 2 - 1);
    else
      insert(id[i] + n * 2, srt[i].id * 2);
  for (int i = 1; i <= n << 1; ++i) {
    int l = 1, r = i, st = i, en = i;
    for (int mid; l <= r;) {
      mid = l + r >> 1;
      if (srt[mid].key >= srt[i].key - dis)
        r = (st = mid) - 1;
      else
        l = mid + 1;
    }
    for (; en >= st && srt[en].id == srt[i].id; --en)
      ;
    if (st <= en)
      addedge(1, st, en, 1, n << 1, srt[i].id * 2 - (srt[i].tp ^ 1));
    // for (int j=st;j<=en;++j)
    // insert(srt[i].id*2-(srt[i].tp^1),srt[j].id*2-srt[j].tp);
    l = i, r = n << 1, st = i, en = i;
    for (int mid; l <= r;) {
      mid = l + r >> 1;
      if (srt[mid].key <= srt[i].key + dis)
        l = (en = mid) + 1;
      else
        r = mid - 1;
    }
    for (; st <= en && srt[st].id == srt[i].id; ++st)
      ;
    if (st <= en)
      addedge(1, st, en, 1, n << 1, srt[i].id * 2 - (srt[i].tp ^ 1));
    // for (int j=st;j<=en;++j)
    // insert(srt[i].id*2-(srt[i].tp^1),srt[j].id*2-srt[j].tp);
  }
  memset(DFN, 0, sizeof DFN), bcnt = idx = 0;
  for (int x = 1; x <= (n << 1) + id[n << 1]; ++x)
    if (!DFN[x])
      tarjan(x);
  for (int i = 1; i <= n; ++i)
    if (bid[i * 2 - 1] == bid[i * 2])
      return 0;
  return 1;
}

void binary_search() {
  int l = 0, r = 1000000000;
  for (int mid; l <= r;) {
    mid = l + r >> 1;
    if (judge(mid))
      l = (ans = mid) + 1;
    else
      r = mid - 1;
  }
}

int main() {
  // freopen("a.in","r",stdin),freopen("a.out","w",stdout);
  n = read();
  for (int i = 1; i <= n; ++i)
    srt[i * 2 - 1].key = x[i] = read(), srt[i * 2 - 1].tp = 0,
                srt[i * 2].key = y[i] = read(), srt[i * 2].tp = 1,
                srt[i * 2 - 1].id = srt[i * 2].id = i;
  sort(srt + 1, srt + 1 + n * 2);
  binary_search(), printf("%d\n", ans);
  // fclose(stdin),fclose(stdout);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stack>

using namespace std;

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch))
    f = ch == '-' ? -1 : f, ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  return x * f;
}

const int N = 10005;
const int LGN = 20;
const int S = N << 3;
const int V = S + (N << 1);
const int E = V + ((N << 2) * LGN);

struct data {
  int key, id;
  bool tp;

  bool operator<(data const d) const {
    return key < d.key || key == d.key && id < d.id;
  }
} srt[N << 1];

int last[V], DFN[V], low[V], bid[V];
int nxt[E], tov[E];
int x[N], y[N];
bool exist[V];
int id[N << 1];
int n, tot, ans, idx, bcnt;

stack<int> st;

inline void insert(int x, int y) {
  tov[++tot] = y, nxt[tot] = last[x], last[x] = tot;
}

void build(int x, int l, int r) {
  if (l == r) {
    id[l] = x;
    return;
  }
  int mid = l + r >> 1;
  build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r),
      insert(x + n * 2, (x << 1) + n * 2),
      insert(x + n * 2, (x << 1 | 1) + n * 2);
}

void addedge(int x, int st, int en, int l, int r, int p) {
  if (st == l && en == r) {
    insert(p, x + n * 2);
    return;
  }
  int mid = l + r >> 1;
  if (en <= mid)
    addedge(x << 1, st, en, l, mid, p);
  else if (mid + 1 <= st)
    addedge(x << 1 | 1, st, en, mid + 1, r, p);
  else
    addedge(x << 1, st, mid, l, mid, p),
        addedge(x << 1 | 1, mid + 1, en, mid + 1, r, p);
}

void tarjan(int x) {
  DFN[x] = low[x] = ++idx, st.push(x), exist[x] = 1;
  for (int i = last[x], y; i; i = nxt[i])
    if (!DFN[y = tov[i]])
      tarjan(y), low[x] = min(low[x], low[y]);
    else if (exist[y])
      low[x] = min(low[x], DFN[y]);
  if (DFN[x] == low[x]) {
    int y;
    ++bcnt;
    do {
      exist[y = st.top()] = 0, st.pop(), bid[y] = bcnt;
    } while (x != y);
  }
}

bool judge(int dis) {
  --dis, memset(last, 0, sizeof last), memset(tov, 0, sizeof tov),
      memset(nxt, 0, sizeof nxt), tot = 0;
  build(1, 1, n << 1);
  for (int i = 1; i <= n << 1; ++i)
    if (srt[i].tp)
      insert(id[i] + n * 2, srt[i].id * 2 - 1);
    else
      insert(id[i] + n * 2, srt[i].id * 2);
  for (int i = 1; i <= n << 1; ++i) {
    int l = 1, r = i, st = i, en = i;
    for (int mid; l <= r;) {
      mid = l + r >> 1;
      if (srt[mid].key >= srt[i].key - dis)
        r = (st = mid) - 1;
      else
        l = mid + 1;
    }
    for (; en >= st && srt[en].id == srt[i].id; --en)
      ;
    if (st <= en)
      addedge(1, st, en, 1, n << 1, srt[i].id * 2 - (srt[i].tp ^ 1));
    // for (int j=st;j<=en;++j)
    // insert(srt[i].id*2-(srt[i].tp^1),srt[j].id*2-srt[j].tp);
    l = i, r = n << 1, st = i, en = i;
    for (int mid; l <= r;) {
      mid = l + r >> 1;
      if (srt[mid].key <= srt[i].key + dis)
        l = (en = mid) + 1;
      else
        r = mid - 1;
    }
    for (; st <= en && srt[st].id == srt[i].id; ++st)
      ;
    if (st <= en)
      addedge(1, st, en, 1, n << 1, srt[i].id * 2 - (srt[i].tp ^ 1));
    // for (int j=st;j<=en;++j)
    // insert(srt[i].id*2-(srt[i].tp^1),srt[j].id*2-srt[j].tp);
  }
  memset(DFN, 0, sizeof DFN), bcnt = idx = 0;
  for (int x = 1; x <= (n << 1) + id[n << 1]; ++x)
    if (!DFN[x])
      tarjan(x);
  for (int i = 1; i <= n; ++i)
    if (bid[i * 2 - 1] == bid[i * 2])
      return 0;
  return 1;
}

void binary_search() {
  int l = 0, r = 1000000000;
  for (int mid; l <= r;) {
    mid = l + r >> 1;
    if (judge(mid))
      l = (ans = mid) + 1;
    else
      r = mid - 1;
  }
}

int main() {
  // freopen("a.in","r",stdin),freopen("a.out","w",stdout);
  n = read();
  for (int i = 1; i <= n; ++i)
    srt[i * 2 - 1].key = x[i] = read(), srt[i * 2 - 1].tp = 0,
                srt[i * 2].key = y[i] = read(), srt[i * 2].tp = 1,
                srt[i * 2 - 1].id = srt[i * 2].id = i;
  sort(srt + 1, srt + 1 + n * 2);
  binary_search(), printf("%d\n", ans);
  // fclose(stdin),fclose(stdout);
  return 0;
}