Problem p03802 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
inline void read(int &r) {
  register char c;
  r = 0;
  do
    c = getchar();
  while (c < '0' || c > '9');
  do
    r = r * 10 + c - '0', c = getchar();
  while (c >= '0' && c <= '9');
}

int L = 1, first[131073], head[131073], _L, n;
struct ac {
  int to, nx;
} e[1000000];
inline void addedge(int u, int a, int v, int b) {
  u = u << 1 | a, v = v << 1 | b;
  e[L].to = v, e[L].nx = first[u], first[u] = L++;
  u ^= 1, v ^= 1;
  e[L].to = u, e[L].nx = first[v], first[v] = L++;
}

int st[131073], top;
int b[131073], timer;
bool dfs(int u) {
  if (b[u ^ 1] == timer)
    return false;

  b[u] = timer;
  st[top++] = u;

  for (int j = first[u]; j; j = e[j].nx)
    if (!(b[e[j].to] == timer || dfs(e[j].to)))
      return false;
  return true;
}

bool check(int u) {
  top = 0;
  if (dfs(u << 1))
    return true;
  while (top)
    b[st[--top]] = 0;
  return dfs(u << 1 | 1);
}

#define x first
#define y second
#define lc now << 1
#define rc now << 1 | 1
std::pair<int, int> a[20000], s[131073];
int pos[10000];

void init(int now = 1, int l = 0, int r = n - 1) {
  if (l == r) {
    if (~pos[a[l].y]) {
      int u = pos[a[l].y];
      addedge(u, 1, now, 0);
      addedge(u, 0, now, 1);
      a[l].y = now;
    } else
      a[l].y = pos[a[l].y] = now;
    s[now].x = s[now].y = a[l].x;
    s[rc].x = 2e9;
    return;
  }
  int m = (l + r) >> 1;
  init(lc, l, m);
  init(rc, m + 1, r);
  s[now].x = s[lc].x;
  s[now].y = s[rc].y;
  addedge(now, 0, lc, 0);
  addedge(now, 0, rc, 0);
}

void link(int u, int L, int R, int now = 1, int l = 0, int r = n - 1) {
  if (L <= l && s[now].y <= R)
    return addedge(u, 1, now, 0);
  int m = (l + r) >> 1;
  if (L <= m)
    link(u, L, R, lc, l, m);
  if (s[rc].x <= R)
    link(u, L, R, rc, m + 1, r);
}

void copy(int now = 1, int l = 0, int r = n - 1) {
  head[now << 1] = first[now << 1];
  head[now << 1 | 1] = first[now << 1 | 1];
  if (l < r) {
    int m = (l + r) >> 1;
    copy(lc, l, m);
    copy(rc, m + 1, r);
  }
}

void paste(int now = 1, int l = 0, int r = n - 1) {
  first[now << 1] = head[now << 1];
  first[now << 1 | 1] = head[now << 1 | 1];
  if (l < r) {
    int m = (l + r) >> 1;
    paste(lc, l, m);
    paste(rc, m + 1, r);
  }
}

bool twosat(int now = 1, int l = 0, int r = n - 1) {
  if (!check(now))
    return false;
  if (l < r) {
    int m = (l + r) >> 1;
    if (!twosat(lc, l, m))
      return false;
    if (!twosat(rc, m + 1, r))
      return false;
  }
  return true;
}

bool work(int d) {
  L = _L, paste();
  for (int i = 0; i < n; i++)
    link(a[i].y, i + 1, a[i].x + d - 1);

  return ++timer, twosat();
}

int main() {
  int i, l = 1e9, m, r = 1;
  read(n);
  for (i = 0; i < n; i++)
    pos[i] = -1;
  n <<= 1;
  for (i = 0; i < n; i++) {
    read(a[i].x);
    a[i].y = i >> 1;
    a[i].x < l && (l = a[i].x);
    a[i].x > r && (r = a[i].x);
  }
  std::sort(a, a + n);

  init(), _L = L, copy();

  r -= l, l = 0;
  while (l < r) {
    m = (l + r + 1) >> 1;
    if (work(m))
      l = m;
    else
      r = m - 1;
  }
  printf("%d\n", l);
}

Fixed submission:
#include <algorithm>
#include <cstdio>
inline void read(int &r) {
  register char c;
  r = 0;
  do
    c = getchar();
  while (c < '0' || c > '9');
  do
    r = r * 10 + c - '0', c = getchar();
  while (c >= '0' && c <= '9');
}

int L = 1, first[131073], head[131073], _L, n;
struct ac {
  int to, nx;
} e[1000000];
inline void addedge(int u, int a, int v, int b) {
  u = u << 1 | a ^ 1, v = v << 1 | b ^ 1;
  e[L].to = v, e[L].nx = first[u], first[u] = L++;
  u ^= 1, v ^= 1;
  e[L].to = u, e[L].nx = first[v], first[v] = L++;
}

int st[131073], top;
int b[131073], timer;
bool dfs(int u) {
  if (b[u ^ 1] == timer)
    return false;

  b[u] = timer;
  st[top++] = u;

  for (int j = first[u]; j; j = e[j].nx)
    if (!(b[e[j].to] == timer || dfs(e[j].to)))
      return false;
  return true;
}

bool check(int u) {
  top = 0;
  if (dfs(u << 1))
    return true;
  while (top)
    b[st[--top]] = 0;
  return dfs(u << 1 | 1);
}

#define x first
#define y second
#define lc now << 1
#define rc now << 1 | 1
std::pair<int, int> a[20000], s[131073];
int pos[10000];

void init(int now = 1, int l = 0, int r = n - 1) {
  if (l == r) {
    if (~pos[a[l].y]) {
      int u = pos[a[l].y];
      addedge(u, 1, now, 0);
      addedge(u, 0, now, 1);
      a[l].y = now;
    } else
      a[l].y = pos[a[l].y] = now;
    s[now].x = s[now].y = a[l].x;
    s[rc].x = 2e9;
    return;
  }
  int m = (l + r) >> 1;
  init(lc, l, m);
  init(rc, m + 1, r);
  s[now].x = s[lc].x;
  s[now].y = s[rc].y;
  addedge(now, 0, lc, 0);
  addedge(now, 0, rc, 0);
}

void link(int u, int L, int R, int now = 1, int l = 0, int r = n - 1) {
  if (L <= l && s[now].y <= R)
    return addedge(u, 1, now, 0);
  int m = (l + r) >> 1;
  if (L <= m)
    link(u, L, R, lc, l, m);
  if (s[rc].x <= R)
    link(u, L, R, rc, m + 1, r);
}

void copy(int now = 1, int l = 0, int r = n - 1) {
  head[now << 1] = first[now << 1];
  head[now << 1 | 1] = first[now << 1 | 1];
  if (l < r) {
    int m = (l + r) >> 1;
    copy(lc, l, m);
    copy(rc, m + 1, r);
  }
}

void paste(int now = 1, int l = 0, int r = n - 1) {
  first[now << 1] = head[now << 1];
  first[now << 1 | 1] = head[now << 1 | 1];
  if (l < r) {
    int m = (l + r) >> 1;
    paste(lc, l, m);
    paste(rc, m + 1, r);
  }
}

bool twosat(int now = 1, int l = 0, int r = n - 1) {
  if (!check(now))
    return false;
  if (l < r) {
    int m = (l + r) >> 1;
    if (!twosat(lc, l, m))
      return false;
    if (!twosat(rc, m + 1, r))
      return false;
  }
  return true;
}

bool work(int d) {
  L = _L, paste();
  for (int i = 0; i < n; i++)
    link(a[i].y, i + 1, a[i].x + d - 1);

  return ++timer, twosat();
}

int main() {
  int i, l = 1e9, m, r = 1;
  read(n);
  for (i = 0; i < n; i++)
    pos[i] = -1;
  n <<= 1;
  for (i = 0; i < n; i++) {
    read(a[i].x);
    a[i].y = i >> 1;
    a[i].x < l && (l = a[i].x);
    a[i].x > r && (r = a[i].x);
  }
  std::sort(a, a + n);

  init(), _L = L, copy();

  r -= l, l = 0;
  while (l < r) {
    m = (l + r + 1) >> 1;
    if (work(m))
      l = m;
    else
      r = m - 1;
  }
  printf("%d\n", l);
}