Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define REV(v) reverse(v.begin(), v.end());
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, start, stop) for (int i = start; i < stop; i++)
#define FORR(i, start, stop) for (int i = start; i > stop; i--)
#define SORT(v, n) sort(v, v + n);
#define SORTR(v, n) sort(v, v + n, greater<int>());
#define VSORT(v) sort(v.begin(), v.end());
#define VSORTR(v) sort(v.begin(), v.end(), greater<int>());
#define REMOVE(v, n) remove(vector<int> v, v + v.size(), int n)
#define ll long long
#define ull unsigned long long
#define pb(a) push_back(a)
#define INF 999999999
#define V(v, i, j) vector(v.begin() + i, v.begin() + j)
#define INSERT(va, vb) va.insert(va.end(), vb.begin(), vb.end())
using namespace std;
typedef vector<int> vint;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef pair<int, P> PP;
typedef pair<ll, LP> LPP;

int dy[] = {0, 0, 1, -1};
int dx[] = {1, -1, 0, 0};

// vector< vector<int> > v (size1, vector<int>(size2) );

struct UnionFind {
  vector<int> par;

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

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

  bool issame(int x, int y) { return root(x) == root(y); }

  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y); // merge technique
    par[x] += par[y];
    par[y] = x;
    return true;
  }

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

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n, m;
  cin >> n >> m;
  vector<ll> A(m), B(m);
  FOR(i, 0, m) cin >> A[i] >> B[i];

  UnionFind uf(n);
  ll ans = n * (n - 1) / 2;
  vector<ll> res;

  FOR(i, 0, m) {
    res.pb(ans);
    ll a = A[m - i - 1], b = B[m - i - 1];
    if (uf.issame(a, b))
      continue;

    ll sa = uf.size(a), sb = uf.size(b);
    ans -= sa * sb;
    uf.merge(a, b);
  }

  REV(res);
  FOR(i, 0, res.size()) cout << res[i] << endl;
}
// 73

Fixed submission:
#include <bits/stdc++.h>
#define REV(v) reverse(v.begin(), v.end());
#define REP(i, n) for (int i = 0; i < n; i++)
#define REPR(i, n) for (int i = n; i >= 0; i--)
#define FOR(i, start, stop) for (int i = start; i < stop; i++)
#define FORR(i, start, stop) for (int i = start; i > stop; i--)
#define SORT(v, n) sort(v, v + n);
#define SORTR(v, n) sort(v, v + n, greater<int>());
#define VSORT(v) sort(v.begin(), v.end());
#define VSORTR(v) sort(v.begin(), v.end(), greater<int>());
#define REMOVE(v, n) remove(vector<int> v, v + v.size(), int n)
#define ll long long
#define ull unsigned long long
#define pb(a) push_back(a)
#define INF 999999999
#define V(v, i, j) vector(v.begin() + i, v.begin() + j)
#define INSERT(va, vb) va.insert(va.end(), vb.begin(), vb.end())
using namespace std;
typedef vector<int> vint;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef pair<int, P> PP;
typedef pair<ll, LP> LPP;

int dy[] = {0, 0, 1, -1};
int dx[] = {1, -1, 0, 0};

// vector< vector<int> > v (size1, vector<int>(size2) );

struct UnionFind {
  vector<int> par;

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

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

  bool issame(int x, int y) { return root(x) == root(y); }

  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (par[x] > par[y])
      swap(x, y); // merge technique
    par[x] += par[y];
    par[y] = x;
    return true;
  }

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

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n, m;
  cin >> n >> m;
  vector<ll> A(m), B(m);
  FOR(i, 0, m) cin >> A[i] >> B[i], A[i]--, B[i]--;

  UnionFind uf(n);
  ll ans = n * (n - 1) / 2;
  vector<ll> res;

  FOR(i, 0, m) {
    res.pb(ans);
    ll a = A[m - i - 1], b = B[m - i - 1];
    if (uf.issame(a, b))
      continue;

    ll sa = uf.size(a), sb = uf.size(b);
    ans -= sa * sb;
    uf.merge(a, b);
  }

  REV(res);
  FOR(i, 0, res.size()) cout << res[i] << endl;
}
// 73