Problem p03858 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>

const int N = 100005;
int X[N], Y[N], fst[N], id1[N], id2[N], n, D, tot = 0;
bool u[N];
long long ans = 0;
struct Edge {
  int to, nxt;
} e[N * 4];

void addedge(int x, int y) {
  e[++tot].to = y;
  e[tot].nxt = fst[x];
  fst[x] = tot;
  e[++tot].to = x;
  e[tot].nxt = fst[y];
  fst[y] = tot;
}

bool cmp(int i, int j) { return X[i] != X[j] ? X[i] < X[j] : Y[i] < Y[j]; }

bool check(int i, int j, int x) {
  return X[i] < X[j] + D || (X[i] == X[j] + D && Y[i] < Y[j] + x);
}

void work1(int *id) {
  for (int i = 1; i <= n; i++)
    id[i] = i;
  std::sort(id + 1, id + n + 1, cmp);
  for (int i = 1, l = 1, r = 1; i <= n; i++) {
    for (; l <= n && check(id[l], id[i], -D); l++)
      ;
    for (; r <= n && check(id[r], id[i], D + 1); r++)
      ;
    if (l == r)
      continue;
    addedge(id[i], id[l]);
    for (; l + 1 < r; l++)
      addedge(id[l], id[l + 1]);
  }
  for (int i = 1; i <= n; i++)
    std::swap(X[i], Y[i]);
}

void work2(int *id, int d) {
  for (int i = 1, l = 1, r = 1; i <= n; i++) {
    for (; l <= n && check(id[l], id[i], -d); l++)
      ;
    for (; r <= n && check(id[r], id[i], d + 1); r++)
      ;
    if (u[id[i]])
      ans += r - l;
  }
  for (int i = 1; i <= n; i++)
    std::swap(X[i], Y[i]);
}

void dfs(int x) {
  if (u[x])
    return;
  u[x] = 1;
  for (int i = fst[x]; i; i = e[i].nxt)
    dfs(e[i].to);
}

int main() {
  int a, b;
  scanf("%d%d%d\n", &n, &a, &b);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    X[i] = x + y;
    Y[i] = x - y;
  }
  D = std::max(abs(X[a] - X[b]), abs(Y[a] - Y[b]));
  work1(id1);
  work1(id2);
  for (int i = 1; i <= n; i++)
    u[i] = 0;
  dfs(a);
  work2(id1, D);
  work2(id2, D - 1);
  printf("%lld\n", ans);
}

Fixed submission:
#include <algorithm>
#include <cstdio>

const int N = 100005;
int X[N], Y[N], fst[N], id1[N], id2[N], n, D, tot = 0;
bool u[N];
long long ans = 0;
struct Edge {
  int to, nxt;
} e[N * 8];

void addedge(int x, int y) {
  e[++tot].to = y;
  e[tot].nxt = fst[x];
  fst[x] = tot;
  e[++tot].to = x;
  e[tot].nxt = fst[y];
  fst[y] = tot;
}

bool cmp(int i, int j) { return X[i] != X[j] ? X[i] < X[j] : Y[i] < Y[j]; }

bool check(int i, int j, int x) {
  return X[i] < X[j] + D || (X[i] == X[j] + D && Y[i] < Y[j] + x);
}

void work1(int *id) {
  for (int i = 1; i <= n; i++)
    id[i] = i;
  std::sort(id + 1, id + n + 1, cmp);
  for (int i = 1, l = 1, r = 1; i <= n; i++) {
    for (; l <= n && check(id[l], id[i], -D); l++)
      ;
    for (; r <= n && check(id[r], id[i], D + 1); r++)
      ;
    if (l == r)
      continue;
    addedge(id[i], id[l]);
    for (; l + 1 < r; l++)
      addedge(id[l], id[l + 1]);
  }
  for (int i = 1; i <= n; i++)
    std::swap(X[i], Y[i]);
}

void work2(int *id, int d) {
  for (int i = 1, l = 1, r = 1; i <= n; i++) {
    for (; l <= n && check(id[l], id[i], -d); l++)
      ;
    for (; r <= n && check(id[r], id[i], d + 1); r++)
      ;
    if (u[id[i]])
      ans += r - l;
  }
  for (int i = 1; i <= n; i++)
    std::swap(X[i], Y[i]);
}

void dfs(int x) {
  if (u[x])
    return;
  u[x] = 1;
  for (int i = fst[x]; i; i = e[i].nxt)
    dfs(e[i].to);
}

int main() {
  int a, b;
  scanf("%d%d%d\n", &n, &a, &b);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    X[i] = x + y;
    Y[i] = x - y;
  }
  D = std::max(abs(X[a] - X[b]), abs(Y[a] - Y[b]));
  work1(id1);
  work1(id2);
  for (int i = 1; i <= n; i++)
    u[i] = 0;
  dfs(a);
  work2(id1, D);
  work2(id2, D - 1);
  printf("%lld\n", ans);
}