Problem p03858 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

#define pb push_back
#define fr first
#define sc second

struct UF {
  int par[100010], r[100010];
  void init() {
    for (int i = 0; i < 100010; i++) {
      par[i] = i;
      r[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit(int x, int y) {
    // cout << "unit" << x << " " << y << endl;
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (r[x] == r[y]) {
        r[x]++;
      }
    }
  }
} uf;

int main() {
  static ll N, a, b;
  static ll x[100010], y[100010];
  scanf("%lld%lld%lld", &N, &a, &b);
  for (int i = 1; i <= N; i++) {
    scanf("%lld%lld", &x[i], &y[i]);
  }
  ll d = abs(x[a] - x[b]) + abs(y[a] - y[b]);

  uf.init();
  static map<ll, map<ll, P>> plus, minus;
  for (int i = 1; i <= N; i++) {
    plus[x[i] + y[i]][x[i]] = P(i, 0);
    minus[x[i] - y[i]][x[i]] = P(i, 0);
  }

  // puts("DEBUG");

  auto nx = plus.begin();
  for (auto mp = plus.begin(); mp != plus.end(); ++mp) {
    // cout << mp->fr << endl;
    while (nx != plus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == plus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    // cout << mp->fr << endl;
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      // cout << itr->fr << " " << itr->sc.fr << endl;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      // cout << itr->fr << " " << itr->sc.fr << endl;
      if (to_l != to_r) {
        // puts("DEBUG");
        uf.unit(itr->sc.fr, to_l->sc.fr);
        // puts("DEBUG");
        /*if(to_l != nx->sc.end())*/ to_l->sc.sc++;
        // puts("DEBUG");
        // if(to_r != nx->sc.end()){
        --to_r;
        to_r->sc.sc--;
        ++to_r;
        // puts("DEBUG");
        // }
      }
      // cout << itr->fr << " " << itr->sc.fr << endl;
    }
    // cout << mp->fr << endl;
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      if (to->sc.sc > 0)
        uf.unit(to->sc.fr, to_->sc.fr);
    }
  }

  // puts("DEBUG");

  nx = minus.begin();
  for (auto mp = minus.begin(); mp != minus.end(); ++mp) {
    while (nx != minus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == minus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        uf.unit(itr->sc.fr, to_l->sc.fr);
        /*if(to_l != nx->sc.end())*/ to_l->sc.sc++;
        // if(to_r != nx->sc.end()){
        --to_r;
        to_r->sc.sc--;
        ++to_r;
        //}
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      if (to->sc.sc > 0)
        uf.unit(to->sc.fr, to_->sc.fr);
    }
  }

  ll ret = 0;
  nx = plus.begin();
  for (auto mp = plus.begin(); mp != plus.end(); ++mp) {
    while (nx != plus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == plus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      to->sc.sc = 0;
    }
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      if (!uf.same(a, itr->sc.fr))
        continue;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr < itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        if (to_l != nx->sc.end())
          to_l->sc.sc++;
        if (to_r != nx->sc.end())
          to_r->sc.sc--;
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      ret += to->sc.sc;
    }
  }
  // cout << ret << endl;
  nx = minus.begin();
  for (auto mp = minus.begin(); mp != minus.end(); ++mp) {
    while (nx != minus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == minus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      to->sc.sc = 0;
    }
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      if (!uf.same(a, itr->sc.fr))
        continue;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr + 1)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        if (to_l != nx->sc.end())
          to_l->sc.sc++;
        if (to_r != nx->sc.end())
          to_r->sc.sc--;
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      ret += to->sc.sc;
    }
  }
  cout << ret << endl;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define pb push_back
#define fr first
#define sc second

struct UF {
  int par[100010], r[100010];
  void init() {
    for (int i = 0; i < 100010; i++) {
      par[i] = i;
      r[i] = 0;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unit(int x, int y) {
    // cout << "unit" << x << " " << y << endl;
    if (same(x, y))
      return;
    x = find(x);
    y = find(y);
    if (r[x] < r[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (r[x] == r[y]) {
        r[x]++;
      }
    }
  }
} uf;

int main() {
  static ll N, a, b;
  static ll x[100010], y[100010];
  scanf("%lld%lld%lld", &N, &a, &b);
  for (int i = 1; i <= N; i++) {
    scanf("%lld%lld", &x[i], &y[i]);
  }
  ll d = abs(x[a] - x[b]) + abs(y[a] - y[b]);

  uf.init();
  static map<ll, map<ll, P>> plus, minus;
  for (int i = 1; i <= N; i++) {
    plus[x[i] + y[i]][x[i]] = P(i, 0);
    minus[x[i] - y[i]][x[i]] = P(i, 0);
  }

  // puts("DEBUG");

  auto nx = plus.begin();
  for (auto mp = plus.begin(); mp != plus.end(); ++mp) {
    // cout << mp->fr << endl;
    while (nx != plus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == plus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    // cout << mp->fr << endl;
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      // cout << itr->fr << " " << itr->sc.fr << endl;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      // cout << itr->fr << " " << itr->sc.fr << endl;
      if (to_l != to_r) {
        // puts("DEBUG");
        uf.unit(itr->sc.fr, to_l->sc.fr);
        // puts("DEBUG");
        /*if(to_l != nx->sc.end())*/ to_l->sc.sc++;
        // puts("DEBUG");
        // if(to_r != nx->sc.end()){
        --to_r;
        to_r->sc.sc--;
        ++to_r;
        // puts("DEBUG");
        // }
      }
      // cout << itr->fr << " " << itr->sc.fr << endl;
    }
    // cout << mp->fr << endl;
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      if (to->sc.sc > 0)
        uf.unit(to->sc.fr, to_->sc.fr);
    }
  }

  // puts("DEBUG");

  nx = minus.begin();
  for (auto mp = minus.begin(); mp != minus.end(); ++mp) {
    while (nx != minus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == minus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        uf.unit(itr->sc.fr, to_l->sc.fr);
        /*if(to_l != nx->sc.end())*/ to_l->sc.sc++;
        // if(to_r != nx->sc.end()){
        --to_r;
        to_r->sc.sc--;
        ++to_r;
        //}
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      if (to->sc.sc > 0)
        uf.unit(to->sc.fr, to_->sc.fr);
    }
  }

  ll ret = 0;
  nx = plus.begin();
  for (auto mp = plus.begin(); mp != plus.end(); ++mp) {
    while (nx != plus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == plus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      to->sc.sc = 0;
    }
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      if (!uf.same(a, itr->sc.fr))
        continue;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr < itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        if (to_l != nx->sc.end())
          to_l->sc.sc++;
        if (to_r != nx->sc.end())
          to_r->sc.sc--;
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      ret += to->sc.sc;
    }
  }
  // cout << ret << endl;
  nx = minus.begin();
  for (auto mp = minus.begin(); mp != minus.end(); ++mp) {
    while (nx != minus.end() && nx->fr < mp->fr + d)
      ++nx;
    if (nx == minus.end())
      break;
    if (nx->fr > mp->fr + d)
      continue;
    auto to_l = nx->sc.begin();
    auto to_r = nx->sc.begin();
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      to->sc.sc = 0;
    }
    for (auto itr = mp->sc.begin(); itr != mp->sc.end(); ++itr) {
      if (!uf.same(a, itr->sc.fr))
        continue;
      while (to_l != nx->sc.end() && to_l->fr < itr->fr + 1)
        ++to_l;
      while (to_r != nx->sc.end() && to_r->fr <= itr->fr + d)
        ++to_r;
      if (to_l != to_r) {
        if (to_l != nx->sc.end())
          to_l->sc.sc++;
        if (to_r != nx->sc.end())
          to_r->sc.sc--;
      }
    }
    for (auto to = nx->sc.begin(); to != nx->sc.end(); ++to) {
      auto to_ = to;
      ++to_;
      to_->sc.sc += to->sc.sc;
      ret += to->sc.sc;
    }
  }
  cout << ret << endl;
}