Problem p03858 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
using namespace std;

const int MAX_N = 100005;

typedef pair<int, int> pii;
typedef long long i64;

class Edge {
public:
  int nxt, to;
} e[MAX_N << 2];

int head[MAX_N], cnt, num[MAX_N];

void addedge(int u, int v) {
  e[++cnt] = (Edge){head[u], v}, head[u] = cnt;
  e[++cnt] = (Edge){head[v], u}, head[v] = cnt;
}

int N, X[MAX_N], Y[MAX_N];

map<int, int> idx;
map<int, int>::iterator iter;
vector<pii> intv[MAX_N], node[MAX_N];

void work(int dx, int dy) {
  idx.clear();

  int tot = 0;
  for (int i = 1; i <= N; ++i) {
    if (idx.count(X[i]) == 0)
      idx[X[i]] = ++tot;
    node[idx[X[i]]].push_back(make_pair(Y[i], i));
  }

  for (int i = 1; i <= tot; ++i)
    sort(node[i].begin(), node[i].end());

  for (iter = idx.begin(); iter != idx.end(); ++iter) {
    if (idx.count(iter->first - dx) == 0)
      continue;
    int pre = idx[iter->first - dx];

    for (pii v : node[iter->second]) {
      int l = lower_bound(node[pre].begin(), node[pre].end(),
                          make_pair(v.first - dy, 0)) -
              node[pre].begin();
      int r = upper_bound(node[pre].begin(), node[pre].end(),
                          make_pair(v.first + dy, N + 1)) -
              node[pre].begin();

      if (l >= r)
        continue;
      intv[pre].push_back(make_pair(l, r - 1));
      addedge(v.second, node[pre][l].second);
      num[v.second] += r - l;
    }
  }

  for (iter = idx.begin(); iter != idx.end(); ++iter) {
    int x = iter->second, l = 0, r = -1;
    sort(intv[x].begin(), intv[x].end());

    for (pii v : intv[x]) {
      if (v.first <= r)
        r = v.second;
      else {
        for (int i = l + 1; i <= r; ++i)
          addedge(node[x][i].second, node[x][i - 1].second);
        l = v.first, r = v.second;
      }
    }
    for (int i = l + 1; i <= r; ++i)
      addedge(node[x][i].second, node[x][i - 1].second);
  }

  for (int i = 1; i <= tot; ++i)
    node[i].clear(), intv[i].clear();
}

i64 res = 0;

bool vis[MAX_N];

void dfs(int x) {
  vis[x] = 1, res += num[x];
  for (int i = head[x]; i; i = e[i].nxt)
    if (!vis[e[i].to])
      dfs(e[i].to);
}

int main() {
  int a, b;

  scanf("%d%d%d", &N, &a, &b);
  for (int i = 1, x, y; i <= N; ++i) {
    scanf("%d%d", &x, &y);
    X[i] = x + y, Y[i] = x - y;
  }

  int d = max(abs(X[a] - X[b]), abs(Y[a] - Y[b]));

  work(d, d);

  for (int i = 1; i <= N; ++i)
    swap(X[i], Y[i]);

  work(d, d - 1);

  dfs(a);

  printf("%lld\n", res);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
using namespace std;

const int MAX_N = 100005;

typedef pair<int, int> pii;
typedef long long i64;

class Edge {
public:
  int nxt, to;
} e[MAX_N << 4];

int head[MAX_N], cnt, num[MAX_N];

void addedge(int u, int v) {
  e[++cnt] = (Edge){head[u], v}, head[u] = cnt;
  e[++cnt] = (Edge){head[v], u}, head[v] = cnt;
}

int N, X[MAX_N], Y[MAX_N];

map<int, int> idx;
map<int, int>::iterator iter;
vector<pii> intv[MAX_N], node[MAX_N];

void work(int dx, int dy) {
  idx.clear();

  int tot = 0;
  for (int i = 1; i <= N; ++i) {
    if (idx.count(X[i]) == 0)
      idx[X[i]] = ++tot;
    node[idx[X[i]]].push_back(make_pair(Y[i], i));
  }

  for (int i = 1; i <= tot; ++i)
    sort(node[i].begin(), node[i].end());

  for (iter = idx.begin(); iter != idx.end(); ++iter) {
    if (idx.count(iter->first - dx) == 0)
      continue;
    int pre = idx[iter->first - dx];

    for (pii v : node[iter->second]) {
      int l = lower_bound(node[pre].begin(), node[pre].end(),
                          make_pair(v.first - dy, 0)) -
              node[pre].begin();
      int r = upper_bound(node[pre].begin(), node[pre].end(),
                          make_pair(v.first + dy, N + 1)) -
              node[pre].begin();

      if (l >= r)
        continue;
      intv[pre].push_back(make_pair(l, r - 1));
      addedge(v.second, node[pre][l].second);
      num[v.second] += r - l;
    }
  }

  for (iter = idx.begin(); iter != idx.end(); ++iter) {
    int x = iter->second, l = 0, r = -1;
    sort(intv[x].begin(), intv[x].end());

    for (pii v : intv[x]) {
      if (v.first <= r)
        r = v.second;
      else {
        for (int i = l + 1; i <= r; ++i)
          addedge(node[x][i].second, node[x][i - 1].second);
        l = v.first, r = v.second;
      }
    }
    for (int i = l + 1; i <= r; ++i)
      addedge(node[x][i].second, node[x][i - 1].second);
  }

  for (int i = 1; i <= tot; ++i)
    node[i].clear(), intv[i].clear();
}

i64 res = 0;

bool vis[MAX_N];

void dfs(int x) {
  vis[x] = 1, res += num[x];
  for (int i = head[x]; i; i = e[i].nxt)
    if (!vis[e[i].to])
      dfs(e[i].to);
}

int main() {
  int a, b;

  scanf("%d%d%d", &N, &a, &b);
  for (int i = 1, x, y; i <= N; ++i) {
    scanf("%d%d", &x, &y);
    X[i] = x + y, Y[i] = x - y;
  }

  int d = max(abs(X[a] - X[b]), abs(Y[a] - Y[b]));

  work(d, d);

  for (int i = 1; i <= N; ++i)
    swap(X[i], Y[i]);

  work(d, d - 1);

  dfs(a);

  printf("%lld\n", res);
  return 0;
}