Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (signed i = 0; i < n; ++i)
#define repi(n) rep(i, n)
#define int long long
#define str string
#define vint vector<int>
#define pint pair<int, int>
#define pb(a) push_back(a)
#define all(v) v.begin(), v.end()
#define yn(b) cout << ((b) ? "Yes" : "No") << endl
#define YN(b) cout << ((b) ? "YES" : "NO") << endl
#define call(a)                                                                \
  for (auto t : a)                                                             \
    cout << t << " ";                                                          \
  cout << endl
#define ENDL printf("\n");
#define debg(a) cout << #a << ":" << a << endl;
#define SORT(a) sort(all(a));
#define INF 1LL << 60
#define inf INF
#define out(i) cout << i << endl;
int min(int a, int b) {
  if (a > b)
    return b;
  return a;
}
int max(int a, int b) {
  if (a > b)
    return a;
  return b;
}

class unionFind {
public:
  vector<int> parent;

  unionFind(int n) { parent = vector<int>(n, -1); }

  int root(int a) {
    if (parent[a] < 0)
      return a;
    return (parent[a] = root(parent[a]));
  }

  int size(int a) { return (-parent[root(a)]); }

  bool connect(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b) {
      return false;
    }
    if (size(a) < size(b))
      swap(a, b);
    parent[a] += parent[b];
    parent[b] = a;
    return true;
  }
};

signed main() {
  int n, m;
  cin >> n >> m;
  vint a(n), b(n);
  rep(i, m) cin >> a[i] >> b[i];
  rep(i, m) a[i]--, b[i]--;
  vint ans(m);
  ans[m - 1] = n * (n - 1) / 2;
  unionFind uni(n);
  for (int i = m - 1; i > 0; --i) {
    ans[i - 1] = ans[i];
    if (uni.root(a[i]) != uni.root(b[i])) {
      ans[i - 1] -= uni.size(a[i]) * uni.size(b[i]);
      uni.connect(a[i], b[i]);
    }
  }
  for (auto i : ans)
    cout << i << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (signed i = 0; i < n; ++i)
#define repi(n) rep(i, n)
#define int long long
#define str string
#define vint vector<int>
#define pint pair<int, int>
#define pb(a) push_back(a)
#define all(v) v.begin(), v.end()
#define yn(b) cout << ((b) ? "Yes" : "No") << endl
#define YN(b) cout << ((b) ? "YES" : "NO") << endl
#define call(a)                                                                \
  for (auto t : a)                                                             \
    cout << t << " ";                                                          \
  cout << endl
#define ENDL printf("\n");
#define debg(a) cout << #a << ":" << a << endl;
#define SORT(a) sort(all(a));
#define INF 1LL << 60
#define inf INF
#define out(i) cout << i << endl;
int min(int a, int b) {
  if (a > b)
    return b;
  return a;
}
int max(int a, int b) {
  if (a > b)
    return a;
  return b;
}

class unionFind {
public:
  vector<int> parent;

  unionFind(int n) { parent = vector<int>(n, -1); }

  int root(int a) {
    if (parent[a] < 0)
      return a;
    return (parent[a] = root(parent[a]));
  }

  int size(int a) { return (-parent[root(a)]); }

  bool connect(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b) {
      return false;
    }
    if (size(a) < size(b))
      swap(a, b);
    parent[a] += parent[b];
    parent[b] = a;
    return true;
  }
};

signed main() {
  int n, m;
  cin >> n >> m;
  vint a(m), b(m);
  rep(i, m) cin >> a[i] >> b[i];
  rep(i, m) a[i]--, b[i]--;
  vint ans(m);
  ans[m - 1] = n * (n - 1) / 2;
  unionFind uni(n);
  for (int i = m - 1; i > 0; --i) {
    ans[i - 1] = ans[i];
    if (uni.root(a[i]) != uni.root(b[i])) {
      ans[i - 1] -= uni.size(a[i]) * uni.size(b[i]);
      uni.connect(a[i], b[i]);
    }
  }
  for (auto i : ans)
    cout << i << endl;

  return 0;
}