Problem p03858 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define maxn 100010
#define mp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch - '0' < 0 || ch - '0' > 9) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch - '0' >= 0 && ch - '0' <= 9) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, A, B, D;
struct P {
  int x, y;
} p[maxn];
int a[maxn], top1;
int b[maxn], top2;
map<pii, int> ma;
set<pii> X[maxn], Y[maxn];
vector<int> f[maxn], g[maxn];
int find1(int x) { return lower_bound(a + 1, a + top1 + 1, x) - a; }
int find2(int x) { return lower_bound(b + 1, b + top2 + 1, x) - b; }
queue<int> q;
ll ans;
int vis[maxn];
void work(set<pii> s, vector<int> v, int l, int r) {
  set<pii>::iterator it = s.lower_bound(mp(l, 0));
  while (it != s.end() && (it->fi) <= r) {
    if (!vis[it->se]) {
      vis[it->se] = 1;
      q.push(it->se);
    }
    set<pii>::iterator it2 = it;
    it2++;
    s.erase(it);
    it = it2;
  }
  int L = lower_bound(v.begin(), v.end(), l) - v.begin();
  int R = upper_bound(v.begin(), v.end(), r) - v.begin();
  ans += R - L;
}
int main() {
  n = read();
  A = read();
  B = read();
  for (int i = 1; i <= n; i++)
    p[i].x = read(), p[i].y = read();
  for (int i = 1; i <= n; i++) {
    int x = p[i].x, y = p[i].y;
    p[i].x = x + y;
    p[i].y = x - y;
    ma[mp(p[i].x, p[i].y)] = 1;
  }
  D = max(abs(p[A].x - p[B].x), abs(p[A].y - p[B].y));
  for (int i = 1; i <= n; i++)
    a[++top1] = p[i].x;
  for (int i = 1; i <= n; i++)
    b[++top2] = p[i].y;
  sort(a + 1, a + top1 + 1);
  top1 = unique(a + 1, a + top1 + 1) - a - 1;
  sort(b + 1, b + top2 + 1);
  top2 = unique(b + 1, b + top2 + 1) - b - 1;
  for (int i = 1; i <= n; i++) {
    X[find1(p[i].x)].insert(mp(p[i].y, i));
    f[find1(p[i].x)].push_back(p[i].y);
    Y[find2(p[i].y)].insert(mp(p[i].x, i));
    g[find2(p[i].y)].push_back(p[i].x);
  }
  for (int i = 1; i <= top1; i++)
    sort(f[i].begin(), f[i].end());
  for (int i = 1; i <= top2; i++)
    sort(g[i].begin(), g[i].end());
  q.push(A);
  vis[A] = 1;
  while (q.size()) {
    int now = q.front();
    q.pop();
    int L = find1(p[now].x - D), R = find1(p[now].x + D);
    int U = find2(p[now].y + D), Dx = find2(p[now].y - D);
    if (a[L] == p[now].x - D)
      work(X[L], f[L], p[now].y - D, p[now].y + D);
    if (a[R] == p[now].x + D)
      work(X[R], f[R], p[now].y - D, p[now].y + D);
    if (b[U] == p[now].y + D)
      work(Y[U], g[U], p[now].x - D, p[now].x + D);
    if (b[Dx] == p[now].y - D)
      work(Y[Dx], g[Dx], p[now].x - D, p[now].x + D);
    ans -= ma[mp(p[now].x - D, p[now].y - D)] +
           ma[mp(p[now].x - D, p[now].y + D)] +
           ma[mp(p[now].x + D, p[now].y - D)] +
           ma[mp(p[now].x + D, p[now].y + D)];
  }
  cout << ans / 2 << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define maxn 100010
#define mp(x, y) make_pair(x, y)
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch - '0' < 0 || ch - '0' > 9) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch - '0' >= 0 && ch - '0' <= 9) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, A, B, D;
struct P {
  int x, y;
} p[maxn];
int a[maxn], top1;
int b[maxn], top2;
map<pii, int> ma;
set<pii> X[maxn], Y[maxn];
vector<int> f[maxn], g[maxn];
int find1(int x) { return lower_bound(a + 1, a + top1 + 1, x) - a; }
int find2(int x) { return lower_bound(b + 1, b + top2 + 1, x) - b; }
queue<int> q;
ll ans;
int vis[maxn];
void work(set<pii> &s, vector<int> v, int l, int r) {
  set<pii>::iterator it = s.lower_bound(mp(l, 0));
  while (it != s.end() && (it->fi) <= r) {
    if (!vis[it->se]) {
      vis[it->se] = 1;
      q.push(it->se);
    }
    set<pii>::iterator it2 = it;
    it2++;
    s.erase(it);
    it = it2;
  }
  int L = lower_bound(v.begin(), v.end(), l) - v.begin();
  int R = upper_bound(v.begin(), v.end(), r) - v.begin();
  ans += R - L;
}
int main() {
  n = read();
  A = read();
  B = read();
  for (int i = 1; i <= n; i++)
    p[i].x = read(), p[i].y = read();
  for (int i = 1; i <= n; i++) {
    int x = p[i].x, y = p[i].y;
    p[i].x = x + y;
    p[i].y = x - y;
    ma[mp(p[i].x, p[i].y)] = 1;
  }
  D = max(abs(p[A].x - p[B].x), abs(p[A].y - p[B].y));
  for (int i = 1; i <= n; i++)
    a[++top1] = p[i].x;
  for (int i = 1; i <= n; i++)
    b[++top2] = p[i].y;
  sort(a + 1, a + top1 + 1);
  top1 = unique(a + 1, a + top1 + 1) - a - 1;
  sort(b + 1, b + top2 + 1);
  top2 = unique(b + 1, b + top2 + 1) - b - 1;
  for (int i = 1; i <= n; i++) {
    X[find1(p[i].x)].insert(mp(p[i].y, i));
    f[find1(p[i].x)].push_back(p[i].y);
    Y[find2(p[i].y)].insert(mp(p[i].x, i));
    g[find2(p[i].y)].push_back(p[i].x);
  }
  for (int i = 1; i <= top1; i++)
    sort(f[i].begin(), f[i].end());
  for (int i = 1; i <= top2; i++)
    sort(g[i].begin(), g[i].end());
  q.push(A);
  vis[A] = 1;
  while (q.size()) {
    int now = q.front();
    q.pop();
    int L = find1(p[now].x - D), R = find1(p[now].x + D);
    int U = find2(p[now].y + D), Dx = find2(p[now].y - D);
    if (a[L] == p[now].x - D)
      work(X[L], f[L], p[now].y - D, p[now].y + D);
    if (a[R] == p[now].x + D)
      work(X[R], f[R], p[now].y - D, p[now].y + D);
    if (b[U] == p[now].y + D)
      work(Y[U], g[U], p[now].x - D, p[now].x + D);
    if (b[Dx] == p[now].y - D)
      work(Y[Dx], g[Dx], p[now].x - D, p[now].x + D);
    ans -= ma[mp(p[now].x - D, p[now].y - D)] +
           ma[mp(p[now].x - D, p[now].y + D)] +
           ma[mp(p[now].x + D, p[now].y - D)] +
           ma[mp(p[now].x + D, p[now].y + D)];
  }
  cout << ans / 2 << endl;
  return 0;
}