Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define int long long
#define double long double
#define rep(i, a, n) for (int i = (int)(a); (i) < (int)(n); ++(i))
#define repe(i, a, n) for (int i = (int)(a); (i) <= (int)(n); ++(i))
#define repif(i, a, x) for (int i = (int)(a); (x); ++(i))
#define repr(i, a, n) for (int i = ((int)(a)-1); (i) >= (int)(n); --(i))
#define reper(i, a, n) for (int i = (int)(a); (i) >= (int)(n); --(i))
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define CEIL(x) ((int)ceil(((double)x)))
#define POW(x, y) ((int)pow(x, y))
#define UNIQUE(x) (x).erase(unique(ALL((x))), end(x))
using namespace std;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using PII = pair<int, int>;
using TIII = tuple<int, int, int>;
using VPII = vector<pair<int, int>>;
using VTIII = vector<tuple<int, int, int>>;
using Complex = complex<double>;
template <typename T> inline bool chmax(T &a, const T &b, bool t = false) {
  if (a < b or (t and a == b)) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> inline bool chmin(T &a, const T &b, bool t = false) {
  if (a > b or (t and a == b)) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> inline bool isin(const T &x, const T &l, const T &r) {
  return l <= x and x < r;
}
inline ostream &fcout(int n = 10) { return cout << fixed << setprecision(n); }
inline ostream &rcout(int n = 2) { return cout << right << setw(n); }
constexpr int64_t INF = numeric_limits<int64_t>::max();
constexpr int32_t INF32 = numeric_limits<int32_t>::max();
constexpr int64_t MOD = 1000000007LL;
constexpr double PI = 3.14159265358979323846264338327950288;
constexpr double EPS = 1e-10;

struct UF {
  int num;
  vector<int> r, p, s;
  UF() = default;
  UF(int sz) : num(sz), r(sz, 1), p(sz, 0), s(sz, 1) {
    iota(begin(p), end(p), 0LL);
  }
  int find(int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
    s[x] += s[y];
    --num;
  }
  int count() const { return num; }
  int size(int x) { return s[find(x)]; }
};

int N, M;
PII AB[100010];
UF uf;
int ans[100010];

int32_t main() {
  cin >> N >> M;
  uf = UF(N);
  repr(i, M, 0) cin >> AB[i].first >> AB[i].second;

  ans[0] = N * (N - 1) / 2;
  rep(i, 0, M) {
    auto [a, b] = AB[i];
    if (uf.same(a, b))
      ans[i + 1] = ans[i];
    else {
      ans[i + 1] = ans[i] - uf.size(a) * uf.size(b);
      uf.unite(a, b);
    }
  }

  repr(i, M, 0) cout << ans[i] << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define int long long
#define double long double
#define rep(i, a, n) for (int i = (int)(a); (i) < (int)(n); ++(i))
#define repe(i, a, n) for (int i = (int)(a); (i) <= (int)(n); ++(i))
#define repif(i, a, x) for (int i = (int)(a); (x); ++(i))
#define repr(i, a, n) for (int i = ((int)(a)-1); (i) >= (int)(n); --(i))
#define reper(i, a, n) for (int i = (int)(a); (i) >= (int)(n); --(i))
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x), end(x)
#define CEIL(x) ((int)ceil(((double)x)))
#define POW(x, y) ((int)pow(x, y))
#define UNIQUE(x) (x).erase(unique(ALL((x))), end(x))
using namespace std;
using VI = vector<int>;
using VVI = vector<vector<int>>;
using PII = pair<int, int>;
using TIII = tuple<int, int, int>;
using VPII = vector<pair<int, int>>;
using VTIII = vector<tuple<int, int, int>>;
using Complex = complex<double>;
template <typename T> inline bool chmax(T &a, const T &b, bool t = false) {
  if (a < b or (t and a == b)) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> inline bool chmin(T &a, const T &b, bool t = false) {
  if (a > b or (t and a == b)) {
    a = b;
    return true;
  }
  return false;
}
template <typename T> inline bool isin(const T &x, const T &l, const T &r) {
  return l <= x and x < r;
}
inline ostream &fcout(int n = 10) { return cout << fixed << setprecision(n); }
inline ostream &rcout(int n = 2) { return cout << right << setw(n); }
constexpr int64_t INF = numeric_limits<int64_t>::max();
constexpr int32_t INF32 = numeric_limits<int32_t>::max();
constexpr int64_t MOD = 1000000007LL;
constexpr double PI = 3.14159265358979323846264338327950288;
constexpr double EPS = 1e-10;

struct UF {
  int num;
  vector<int> r, p, s;
  UF() = default;
  UF(int sz) : num(sz), r(sz, 1), p(sz, 0), s(sz, 1) {
    iota(begin(p), end(p), 0LL);
  }
  int find(int x) { return (x == p[x] ? x : p[x] = find(p[x])); }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
    s[x] += s[y];
    --num;
  }
  int count() const { return num; }
  int size(int x) { return s[find(x)]; }
};

int N, M;
PII AB[100010];
UF uf;
int ans[100010];

int32_t main() {
  cin >> N >> M;
  uf = UF(N);
  repr(i, M, 0) cin >> AB[i].first >> AB[i].second;

  ans[0] = N * (N - 1) / 2;
  rep(i, 0, M) {
    auto [a, b] = AB[i];
    a--;
    b--;
    if (uf.same(a, b))
      ans[i + 1] = ans[i];
    else {
      ans[i + 1] = ans[i] - uf.size(a) * uf.size(b);
      uf.unite(a, b);
    }
  }

  repr(i, M, 0) cout << ans[i] << endl;

  return 0;
}