Problem p02998 (C++)

Buggy submission (status: Time Limit Exceeded):
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (b - 1); i >= (a); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n - 1); i >= 0; i--)
#define REP1(i, n) for (int i = 1; i <= (n); i++)
#define RREP1(i, n) for (int i = (n); i >= 1; i--)
#define ALL(a) (a).begin(), (a).end()
#define UNIQUE_SORT(l)                                                         \
  sort(ALL(l));                                                                \
  l.erase(unique(ALL(l)), l.end());
#define CONTAIN(a, b) find(ALL(a), (b)) != (a).end()
#define out(...) printf(__VA_ARGS__)
#if DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...) /* ... */
#endif
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
void _OUT(){};
template <class H, class... T> void _OUT(H &h, T &...t) {
  cout << ' ' << h;
  _OUT(t...);
};
template <class H, class... T> void _P(H &h, T &...t) {
  cout << h;
  _OUT(t...);
};
#define _PN(...)                                                               \
  _P(__VA_ARGS__);                                                             \
  cout << endl;
#define EXEC(...)                                                              \
  void exec() { (__VA_ARGS__ - 1) ? multi() : solve(0); }

void exec();
void solve(int t);
void multi() {
  int TT;
  cin >> TT;
  REP1(t, TT) solve(t);
}
signed main() {
#if DEBUG
  std::ifstream in("input.txt");
  std::cin.rdbuf(in.rdbuf());
#endif
  cin.tie(0);
  ios::sync_with_stdio(false);
  exec();
  return 0;
}

/*================================*/
#if DEBUG
#define SIZE 123450
#else
#define SIZE 123450
#endif

int N, M;
vector<int> A(SIZE);

struct UnionFind {
  vector<int> parent;
  int size;
  vector<set<int>> V;
  UnionFind(int size) { reset(size); }
  void reset(int size) {
    this->size = size;
    parent.resize(size);
    REP(i, size) parent[i] = i;
    V.resize(size);
    REP(i, size) V[i].insert(i);
  }
  int root(int i) {
    if (parent[i] == i)
      return i;
    return parent[i] = root(parent[i]);
  }
  void merge(int i, int j) {
    int ir = root(i);
    int jr = root(j);
    if (ir == jr)
      return;
    int next = (V[ir].size() <= V[jr].size()) ? ir : jr;
    int hide = (ir == next) ? jr : ir;
    parent[ir] = parent[jr] = next;
    for (int n : V[hide])
      V[next].insert(n);
    V[hide].clear();
  }
  bool same(int i, int j) { return root(i) == root(j); }
  int vsize(int i) { return (int)V[i].size(); }
};

void solve(int _t) {
  cin >> N;
  auto uf = new UnionFind(SIZE);
  int x, y;
  set<int> ylist[SIZE];
  vector<pair<int, int>> V;
  REP(i, N) {
    cin >> x >> y;
    ylist[x].insert(y);
    V.push_back({x, y});
  }
  REP(i, SIZE) if (ylist[i].size()) {
    int y0 = *ylist[i].begin();
    for (int y : ylist[i]) {
      uf->merge(y0, y);
    }
  }
  vector<set<int>> xlist(SIZE);
  for (auto p : V) {
    xlist[uf->root(p.second)].insert(p.first);
    debug("xlist[%lld].insert(%lld)\n", uf->root(p.second), p.first);
  }
  int ans = -N;
  REP(i, SIZE) { ans += xlist[i].size() * uf->vsize(i); }
  _PN(ans);
}
EXEC(1)


Fixed submission:
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (b - 1); i >= (a); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n - 1); i >= 0; i--)
#define REP1(i, n) for (int i = 1; i <= (n); i++)
#define RREP1(i, n) for (int i = (n); i >= 1; i--)
#define ALL(a) (a).begin(), (a).end()
#define UNIQUE_SORT(l)                                                         \
  sort(ALL(l));                                                                \
  l.erase(unique(ALL(l)), l.end());
#define CONTAIN(a, b) find(ALL(a), (b)) != (a).end()
#define out(...) printf(__VA_ARGS__)
#if DEBUG
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...) /* ... */
#endif
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
void _OUT(){};
template <class H, class... T> void _OUT(H &h, T &...t) {
  cout << ' ' << h;
  _OUT(t...);
};
template <class H, class... T> void _P(H &h, T &...t) {
  cout << h;
  _OUT(t...);
};
#define _PN(...)                                                               \
  _P(__VA_ARGS__);                                                             \
  cout << endl;
#define EXEC(...)                                                              \
  void exec() { (__VA_ARGS__ - 1) ? multi() : solve(0); }

void exec();
void solve(int t);
void multi() {
  int TT;
  cin >> TT;
  REP1(t, TT) solve(t);
}
signed main() {
#if DEBUG
  std::ifstream in("input.txt");
  std::cin.rdbuf(in.rdbuf());
#endif
  cin.tie(0);
  ios::sync_with_stdio(false);
  exec();
  return 0;
}

/*================================*/
#if DEBUG
#define SIZE 123450
#else
#define SIZE 123450
#endif

int N, M;
vector<int> A(SIZE);

struct UnionFind {
  vector<int> parent;
  int size;
  vector<set<int>> V;
  UnionFind(int size) { reset(size); }
  void reset(int size) {
    this->size = size;
    parent.resize(size);
    REP(i, size) parent[i] = i;
    V.resize(size);
    REP(i, size) V[i].insert(i);
  }
  int root(int i) {
    if (parent[i] == i)
      return i;
    return parent[i] = root(parent[i]);
  }
  void merge(int i, int j) {
    int ir = root(i);
    int jr = root(j);
    if (ir == jr)
      return;
    int next = (V[ir].size() >= V[jr].size()) ? ir : jr;
    int hide = (ir == next) ? jr : ir;
    parent[ir] = parent[jr] = next;
    for (int n : V[hide])
      V[next].insert(n);
    V[hide].clear();
  }
  bool same(int i, int j) { return root(i) == root(j); }
  int vsize(int i) { return (int)V[i].size(); }
};

void solve(int _t) {
  cin >> N;
  auto uf = new UnionFind(SIZE);
  int x, y;
  set<int> ylist[SIZE];
  vector<pair<int, int>> V;
  REP(i, N) {
    cin >> x >> y;
    ylist[x].insert(y);
    V.push_back({x, y});
  }
  REP(i, SIZE) if (ylist[i].size()) {
    int y0 = *ylist[i].begin();
    for (int y : ylist[i]) {
      uf->merge(y0, y);
    }
  }
  vector<set<int>> xlist(SIZE);
  for (auto p : V) {
    xlist[uf->root(p.second)].insert(p.first);
    debug("xlist[%lld].insert(%lld)\n", uf->root(p.second), p.first);
  }
  int ans = -N;
  REP(i, SIZE) { ans += xlist[i].size() * uf->vsize(i); }
  _PN(ans);
}
EXEC(1)