Problem p02998 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vii vector<int>
#define vll vector<ll>
#define lb lower_bound
#define pb push_back
#define mp make_pair
#define rep(i, n) for (ll i = 0; i < n; i++)
#define rep2(i, a, b) for (ll i = a; i < b; i++)
#define repr(i, n) for (ll i = n - 1; i >= 0; i--)
#define all(x) x.begin(), x.end()
#define INF (1 << 30) - 1
#define LLINF (1LL << 61) - 1
#define int ll
using namespace std;
const int MOD = 1000000007;
const int MAX = 510000;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }

  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }

  bool same(int x, int y) { return find(x) == find(y); }

  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int x) { return -par[find(x)]; }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  ll ans = 0;
  vii x, y;
  const int MAX = 11000;
  cin >> n;
  x.resize(n);
  y.resize(n);
  UnionFind uf(MAX * 2);
  rep(i, n) {
    cin >> x[i] >> y[i];
    uf.unite(x[i], y[i] + MAX);
  }
  map<int, ll> mx, my;
  rep(i, MAX) { mx[uf.find(i)]++; }
  rep2(i, MAX, MAX * 2) { my[uf.find(i)]++; }
  rep(i, MAX * 2) { ans += mx[i] * my[i]; }
  cout << ans - n << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vii vector<int>
#define vll vector<ll>
#define lb lower_bound
#define pb push_back
#define mp make_pair
#define rep(i, n) for (ll i = 0; i < n; i++)
#define rep2(i, a, b) for (ll i = a; i < b; i++)
#define repr(i, n) for (ll i = n - 1; i >= 0; i--)
#define all(x) x.begin(), x.end()
#define INF (1 << 30) - 1
#define LLINF (1LL << 61) - 1
#define int ll
using namespace std;
const int MOD = 1000000007;
const int MAX = 510000;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }

  int find(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = find(par[x]);
  }

  bool same(int x, int y) { return find(x) == find(y); }

  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  int size(int x) { return -par[find(x)]; }
};

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n;
  ll ans = 0;
  vii x, y;
  const int MAX = 110000;
  cin >> n;
  x.resize(n);
  y.resize(n);
  UnionFind uf(MAX * 2);
  rep(i, n) {
    cin >> x[i] >> y[i];
    uf.unite(x[i], y[i] + MAX);
  }
  map<int, ll> mx, my;
  rep(i, MAX) { mx[uf.find(i)]++; }
  rep2(i, MAX, MAX * 2) { my[uf.find(i)]++; }
  rep(i, MAX * 2) { ans += mx[i] * my[i]; }
  cout << ans - n << endl;
  return 0;
}