prithivMLmods/Coder-Stat huggingface dataset:
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
using namespace std;
static const int MAX_N = 100, MAX_M = 10e2;

struct UnionFind { // MAX_N定義必要要素数

  int Par[MAX_N]; // 親は"-子供(自分含め)"を所持
  int N;
  UnionFind(int n) {
    N = n;
    for (int i = 0; i < N; i++)
      Par[i] = -1;
  }
  bool unite(int a, int b) {
    int par_a = find(a);
    int par_b = find(b);
    if (par_a == par_b)
      return true;
    if (Par[par_a] > Par[par_b])
      swap(par_a, par_b);
    Par[par_a] += Par[par_b];
    Par[par_b] = par_a;
    return false;
  }
  int find(int a) {
    if (Par[a] < 0)
      return a;
    else
      return find(Par[a]);
  }
  long sizek(int a) {
    if (Par[a] < 0)
      return Par[a] * (-1);
    else
      return sizek(Par[a]);
  }
};
/*
UnionFind XX(頂点の数)
XX.unite(a,b);a,b接続  既接続->true  新接続->false
find(a)aの親の番号返却
sizek(a)aの群れの頂点の数返却
*/
int A[MAX_M], B[MAX_M];
long ANS[MAX_M];
int main(void) {
  int N, M;
  cin >> N >> M;
  UnionFind uni(N);
  for (int i = 0; i < M; i++)
    cin >> A[i] >> B[i];
  ANS[M - 1] = (long)N * (N - 1) / 2;

  for (int i = M - 1; i >= 1; i--) {
    A[i]--;
    B[i]--;
    int ba = uni.find(A[i]);
    int bb = uni.find(B[i]);
    if (ba == bb) {
      ANS[i - 1] = ANS[i];
      continue;
    }
    long res = uni.sizek(A[i]);
    res *= (long)uni.sizek(B[i]);
    ANS[i - 1] = ANS[i] - res;
    uni.unite(A[i], B[i]);
  }

  for (int i = 0; i < M; i++)
    cout << ANS[i] << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
using namespace std;
static const int MAX_N = 10e5, MAX_M = 10e5;

struct UnionFind { // MAX_N定義必要要素数

  int Par[MAX_N]; // 親は"-子供(自分含め)"を所持
  int N;
  UnionFind(int n) {
    N = n;
    for (int i = 0; i < N; i++)
      Par[i] = -1;
  }
  bool unite(int a, int b) {
    int par_a = find(a);
    int par_b = find(b);
    if (par_a == par_b)
      return true;
    if (Par[par_a] > Par[par_b])
      swap(par_a, par_b);
    Par[par_a] += Par[par_b];
    Par[par_b] = par_a;
    return false;
  }
  int find(int a) {
    if (Par[a] < 0)
      return a;
    else
      return find(Par[a]);
  }
  long sizek(int a) {
    if (Par[a] < 0)
      return Par[a] * (-1);
    else
      return sizek(Par[a]);
  }
};
/*
UnionFind XX(頂点の数)
XX.unite(a,b);a,b接続  既接続->true  新接続->false
find(a)aの親の番号返却
sizek(a)aの群れの頂点の数返却
*/
int A[MAX_M], B[MAX_M];
long ANS[MAX_M];
int main(void) {
  int N, M;
  cin >> N >> M;
  UnionFind uni(N);
  for (int i = 0; i < M; i++)
    cin >> A[i] >> B[i];
  ANS[M - 1] = (long)N * (N - 1) / 2;

  for (int i = M - 1; i >= 1; i--) {
    A[i]--;
    B[i]--;
    int ba = uni.find(A[i]);
    int bb = uni.find(B[i]);
    if (ba == bb) {
      ANS[i - 1] = ANS[i];
      continue;
    }
    long res = uni.sizek(A[i]);
    res *= (long)uni.sizek(B[i]);
    ANS[i - 1] = ANS[i] - res;
    uni.unite(A[i], B[i]);
  }

  for (int i = 0; i < M; i++)
    cout << ANS[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
// Robs Code
#include <bits/stdc++.h>
#define speed                                                                  \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define ll long long int
#define fri(l, k) for (i = l; i <= k; i++)
#define frj(l, k) for (j = l; j >= k; j--)
#define all(x) x.begin(), x.end()
#define ed cout << "\n";
#define pb push_back
#define pii pair<ll, ll>
#define _1 first
#define _2 second
#define maxi 100000007
/**********************************************************/
using namespace std;
ll i, j, k, n, m, q, t, a, b, c, cnt, sum, tot;
ll part[10001], sz[100001], cur, connect;
void init(ll n) {
  for (i = 1; i <= n; i++) {
    part[i] = i;
    sz[i] = 1;
  }
  connect = n;
}
ll findParent(ll k) {
  while (k != part[k]) {
    part[k] = part[part[k]];
    k = part[k];
  }
  return k;
}
// ll findParent(ll k){
//     return part[k]==k?k:part[k]=findParent(k);
// }
void unite(ll x, ll y) {
  x = findParent(x), y = findParent(y);
  if (x == y)
    return;
  cur -= (sz[x] * sz[y]);
  sz[x] += sz[y];
  sz[y] = 0;
  part[y] = x;
}
int main() {
  speed;
  cin >> n >> m;
  init(n);
  vector<pii> v(m);
  fri(0, m - 1) cin >> v[i]._1 >> v[i]._2;
  vector<ll> ans;
  cur = n * (n - 1) / 2;
  for (i = m - 1; i >= 0; i--) {
    ans.pb(cur);
    unite(v[i]._1, v[i]._2);
  }
  for (i = ans.size() - 1; i >= 0; i--)
    cout << ans[i] << endl;
  return 0;
}


Fixed submission:
// Robs Code
#include <bits/stdc++.h>
#define speed                                                                  \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define ll long long int
#define fri(l, k) for (i = l; i <= k; i++)
#define frj(l, k) for (j = l; j >= k; j--)
#define all(x) x.begin(), x.end()
#define ed cout << "\n";
#define pb push_back
#define pii pair<ll, ll>
#define _1 first
#define _2 second
#define maxi 100000007
/**********************************************************/
using namespace std;
ll i, j, k, n, m, q, t, a, b, c, cnt, sum, tot;
ll part[100001], sz[100001], cur, connect;
void init(ll n) {
  for (i = 1; i <= n; i++) {
    part[i] = i;
    sz[i] = 1;
  }
  connect = n;
}
ll findParent(ll k) {
  while (k != part[k]) {
    part[k] = part[part[k]];
    k = part[k];
  }
  return k;
}
// ll findParent(ll k){
//     return part[k]==k?k:part[k]=findParent(k);
// }
void unite(ll x, ll y) {
  x = findParent(x), y = findParent(y);
  if (x == y)
    return;
  cur -= (sz[x] * sz[y]);
  sz[x] += sz[y];
  sz[y] = 0;
  part[y] = x;
}
int main() {
  speed;
  cin >> n >> m;
  init(n);
  vector<pii> v(m);
  fri(0, m - 1) cin >> v[i]._1 >> v[i]._2;
  vector<ll> ans;
  cur = n * (n - 1) / 2;
  for (i = m - 1; i >= 0; i--) {
    ans.pb(cur);
    unite(v[i]._1, v[i]._2);
  }
  for (i = ans.size() - 1; i >= 0; i--)
    cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <vector>
using namespace std;
class UnionFind {
public:
  // 親の番号を格納。親なら-(その集合のサイズ)
  vector<int> Parent;

  UnionFind(int N) { Parent = vector<int>(N, -1); }
  // Aのグループを調べる
  int root(int A) {
    if (Parent[A] < 0)
      return A;
    return Parent[A] = root(Parent[A]);
  }
  // 自分のいるグループの頂点数を調べる
  int size(int A) { return -Parent[root(A)]; }
  // AとBをくっつける
  bool connect(int A, int B) {
    // AとBを直接くっつけず、親どうしをくっつける
    A = root(A);
    B = root(B);
    if (A == B) { // すでにくっついてる
      return false;
    }
    // おおきいほうを親にしたい
    if (size(A) < size(B))
      swap(A, B);
    // Aのサイズを更新
    Parent[A] += Parent[B];
    // BをAにつるす
    Parent[B] = A;
    return true;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(M), B(M);
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }
  vector<long long> ans(M);
  ans[M - 1] = (long long)N * (N - 1) / 2;

  UnionFind Uni(N);

  for (int i = M - 1; i >= 0; i--) {
    if (Uni.root(A[i]) != Uni.root(B[i])) {
      ans[i - 1] = ans[i] - (long long)Uni.size(A[i]) * Uni.size(B[i]);
      Uni.connect(A[i], B[i]);
    } else {
      ans[i - 1] = ans[i];
    }
  }
  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}

Fixed submission:
#include <iostream>
#include <vector>
using namespace std;
class UnionFind {
public:
  // 親の番号を格納。親なら-(その集合のサイズ)
  vector<int> Parent;

  UnionFind(int N) { Parent = vector<int>(N, -1); }
  // Aのグループを調べる
  int root(int A) {
    if (Parent[A] < 0)
      return A;
    return Parent[A] = root(Parent[A]);
  }
  // 自分のいるグループの頂点数を調べる
  int size(int A) { return -Parent[root(A)]; }
  // AとBをくっつける
  bool connect(int A, int B) {
    // AとBを直接くっつけず、親どうしをくっつける
    A = root(A);
    B = root(B);
    if (A == B) { // すでにくっついてる
      return false;
    }
    // おおきいほうを親にしたい
    if (size(A) < size(B))
      swap(A, B);
    // Aのサイズを更新
    Parent[A] += Parent[B];
    // BをAにつるす
    Parent[B] = A;
    return true;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(M), B(M);
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }
  vector<long long> ans(M);
  ans[M - 1] = (long long)N * (N - 1) / 2;

  UnionFind Uni(N);

  for (int i = M - 1; i > 0; i--) {
    if (Uni.root(A[i]) != Uni.root(B[i])) {
      ans[i - 1] = ans[i] - (long long)Uni.size(A[i]) * Uni.size(B[i]);
      Uni.connect(A[i], B[i]);
    } else {
      ans[i - 1] = ans[i];
    }
  }
  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <cstdio>
#include <iostream>

using namespace std;

#define LLInt long long int

LLInt n, m;
int par[100001];
LLInt t_size[100001];

int find(int x) {
  if (par[x] == x)
    return x;
  int res = find(par[x]);
  return res;
}

void unite(int x, int y) {
  int rootx = find(x), rooty = find(y);
  par[rooty] = rootx;
  t_size[rootx] += t_size[rooty];
}

int main() {
  int a[100001], b[100001];
  cin >> n >> m;

  for (int i = 0; i < m; i++) {
    scanf("%d %d", &a[i], &b[i]);
  }

  // init
  for (int i = 0; i <= 100000; i++) {
    par[i] = i;
    t_size[i] = 1;
  }

  LLInt ans[100000];
  ans[m - 1] = n * (n - 1) / 2;
  for (int i = 2; i <= m; i++) {
    int roota = find(a[m - i + 1]), rootb = find(b[m - i + 1]);

    ans[m - i] = ans[m - i + 1];

    if (roota != rootb) {
      ans[m - i] -= t_size[roota] * t_size[rootb];
      unite(roota, rootb);
    }
  }

  for (int i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }

  return 0;
}

Fixed submission:
#include <cstdio>
#include <iostream>

using namespace std;

#define LLInt long long int

LLInt n, m;
int par[100001];
LLInt t_size[100001];

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

void unite(int x, int y) {
  int rootx = find(x), rooty = find(y);
  par[rooty] = rootx;
  t_size[rootx] += t_size[rooty];
}

int main() {
  int a[100001], b[100001];
  cin >> n >> m;

  for (int i = 0; i < m; i++) {
    scanf("%d %d", &a[i], &b[i]);
  }

  // init
  for (int i = 0; i <= 100000; i++) {
    par[i] = i;
    t_size[i] = 1;
  }

  LLInt ans[100000];
  ans[m - 1] = n * (n - 1) / 2;
  for (int i = 2; i <= m; i++) {
    int roota = find(a[m - i + 1]), rootb = find(b[m - i + 1]);

    ans[m - i] = ans[m - i + 1];

    if (roota != rootb) {
      ans[m - i] -= t_size[roota] * t_size[rootb];
      unite(roota, rootb);
    }
  }

  for (int i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }

  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

class UnionFind {
  vector<int> par;
  int groupCount;

public:
  // UnionFind uf(n)でn要素のUF木uf
  UnionFind(int n = 0) { init(n); }

  // n要素で初期化
  void init(int n = 0) {
    par.resize(n);
    fill(par.begin(), par.end(), -1);
    groupCount = n;
    return;
  }

  // xが属する集合の根を求める
  int root(int x) {
    if (par[x] < 0) {
      return x;
    }
    return par[x] = root(par[x]);
  }

  // xとyが同じ集合に属するか調べる
  bool same(int x, int y) { return root(x) == root(y); }

  // xが属する集合の大きさを調べる
  int size(int x) { return -par[root(x)]; }

  // xが属する集合とyが属する集合を繋ぐ
  // 既に繋がっていたらfalseが返る
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return false;
    }
    if (par[y] < par[x]) {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    --groupCount;
    return true;
  }

  // UF内にある集合の個数を調べる
  int size(void) { return groupCount; }
};

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

  int n, m;
  cin >> n >> m;

  vector<int> a(n), b(n);
  for (int i = 0; i < m; ++i) {
    cin >> a[i] >> b[i];
    --a[i];
    --b[i];
  }

  UnionFind uf(n);
  vector<long long> ans(m);
  long long now = (long long)n * (n - 1LL) / 2LL;
  for (int i = m - 1; i >= 0; --i) {
    ans[i] = now;
    long long as = uf.size(a[i]), bs = uf.size(b[i]);
    if (uf.unite(a[i], b[i])) {
      now -= as * bs;
    }
  }

  for (int i = 0; i < m; ++i) {
    cout << ans[i] << endl;
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

class UnionFind {
  vector<int> par;
  int groupCount;

public:
  // UnionFind uf(n)でn要素のUF木uf
  UnionFind(int n = 0) { init(n); }

  // n要素で初期化
  void init(int n = 0) {
    par.resize(n);
    fill(par.begin(), par.end(), -1);
    groupCount = n;
    return;
  }

  // xが属する集合の根を求める
  int root(int x) {
    if (par[x] < 0) {
      return x;
    }
    return par[x] = root(par[x]);
  }

  // xとyが同じ集合に属するか調べる
  bool same(int x, int y) { return root(x) == root(y); }

  // xが属する集合の大きさを調べる
  int size(int x) { return -par[root(x)]; }

  // xが属する集合とyが属する集合を繋ぐ
  // 既に繋がっていたらfalseが返る
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) {
      return false;
    }
    if (par[y] < par[x]) {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    --groupCount;
    return true;
  }

  // UF内にある集合の個数を調べる
  int size(void) { return groupCount; }
};

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

  int n, m;
  cin >> n >> m;

  vector<int> a(m), b(m);
  for (int i = 0; i < m; ++i) {
    cin >> a[i] >> b[i];
    --a[i];
    --b[i];
  }

  UnionFind uf(n);
  vector<long long> ans(m);
  long long now = (long long)n * (n - 1LL) / 2LL;
  for (int i = m - 1; i >= 0; --i) {
    ans[i] = now;
    long long as = uf.size(a[i]), bs = uf.size(b[i]);
    if (uf.unite(a[i], b[i])) {
      now -= as * bs;
    }
  }

  for (int i = 0; i < m; ++i) {
    cout << ans[i] << endl;
  }

  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;

#define INF (i64)(1e18)
#define MOD (i64)(1e9 + 7)
#define REP(i, n) for (i64 i = 0; i < (n); i++)
#define RREP(i, n) for (i64 i = (n)-1; i >= 0; i--)
#define RANGE(i, a, b) for (i64 i = (a); i < (b); i++)
#define RRANGE(i, a, b) for (i64 i = (b)-1; i >= (a); i--)
#define ALL(v) (v).begin(), (v).end()
#define SIZE(v) ((i64)(v).size())
template <class T> inline void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}

struct UnionFind {
  vector<i64> par, sz;
  UnionFind(i64 n) : par(n), sz(n, 1) { REP(i, n) par[i] = i; }
  i64 root(i64 x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  void unite(i64 x, i64 y) {
    i64 rx = root(x), ry = root(y);
    if (rx == ry)
      return;
    if (size(rx) < size(ry))
      swap(rx, ry);
    par[ry] = rx;
    sz[rx] += sz[ry];
  }
  i64 size(i64 x) { return sz[root(x)]; }
  bool same(i64 x, i64 y) { return root(x) == root(y); }
};

int main() {
  i64 n, m;
  cin >> n >> m;
  vector<i64> a(m), b(m);
  REP(i, m) {
    cin >> a.at(i) >> b.at(i);
    a[i]--;
    b[i]--;
  }

  UnionFind uf(n);
  i64 memo = n * (n - 1) / 2;
  vector<i64> ans(n);
  RREP(i, m) {
    ans[i] = memo;
    if (uf.same(a[i], b[i]))
      continue;
    memo -= uf.size(a[i]) * uf.size(b[i]);
    uf.unite(a[i], b[i]);
  }
  for (auto &x : ans)
    cout << x << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;

#define INF (i64)(1e18)
#define MOD (i64)(1e9 + 7)
#define REP(i, n) for (i64 i = 0; i < (n); i++)
#define RREP(i, n) for (i64 i = (n)-1; i >= 0; i--)
#define RANGE(i, a, b) for (i64 i = (a); i < (b); i++)
#define RRANGE(i, a, b) for (i64 i = (b)-1; i >= (a); i--)
#define ALL(v) (v).begin(), (v).end()
#define SIZE(v) ((i64)(v).size())
template <class T> inline void chmax(T &a, const T &b) {
  if (a < b)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (a > b)
    a = b;
}

struct UnionFind {
  vector<i64> par, sz;
  UnionFind(i64 n) : par(n), sz(n, 1) { REP(i, n) par[i] = i; }
  i64 root(i64 x) {
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }
  void unite(i64 x, i64 y) {
    i64 rx = root(x), ry = root(y);
    if (rx == ry)
      return;
    if (size(rx) < size(ry))
      swap(rx, ry);
    par[ry] = rx;
    sz[rx] += sz[ry];
  }
  i64 size(i64 x) { return sz[root(x)]; }
  bool same(i64 x, i64 y) { return root(x) == root(y); }
};

int main() {
  i64 n, m;
  cin >> n >> m;
  vector<i64> a(m), b(m);
  REP(i, m) {
    cin >> a.at(i) >> b.at(i);
    a[i]--;
    b[i]--;
  }

  UnionFind uf(n);
  i64 memo = n * (n - 1) / 2;
  vector<i64> ans(m);
  RREP(i, m) {
    ans[i] = memo;
    if (uf.same(a[i], b[i]))
      continue;
    memo -= uf.size(a[i]) * uf.size(b[i]);
    uf.unite(a[i], b[i]);
  }
  for (auto &x : ans)
    cout << x << endl;

  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

struct UnionFind {
  vector<long> par;

  UnionFind(long N) : par(N) {
    for (long i = 0; i < N; ++i)
      par[i] = i;
  }

  long root(long x) {
    if (par[x] == x)
      return x;
    else
      root(par[x]);
  }

  void unite(long x, long y) {
    long rx = root(x);
    long ry = root(y);
    if (rx == ry)
      return;
    else
      par[rx] = ry;
  }

  bool same(long x, long y) {
    long rx = root(x);
    long ry = root(y);
    return rx == ry;
  }
};

int main() {
  long N, M;
  cin >> N >> M;
  long A[M], B[M];
  for (long i = 0; i < M; ++i) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  UnionFind tree(N);

  long ans[M];
  ans[M - 1] = N * (N - 1) / 2;
  map<long, long> size;

  for (long i = 0; i < N; ++i) {
    size[i] = 1;
  }

  for (long i = M - 1; i >= 0; --i) {
    if (!tree.same(A[i], B[i]) & i > 0) {
      ans[i - 1] = ans[i] - size[tree.root(A[i])] * size[tree.root(B[i])];
      long a = size[tree.root(A[i])];
      long b = size[tree.root(B[i])];
      size[tree.root(A[i])] += b;
      size[tree.root(B[i])] += a;
      tree.unite(A[i], B[i]);
    } else if (i > 0) {
      ans[i - 1] = ans[i];
    }
  }
  for (long i = 0; i < M; ++i) {
    cout << ans[i] << endl;
  }
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

struct UnionFind {
  vector<long> par;

  UnionFind(long N) : par(N) {
    for (long i = 0; i < N; ++i)
      par[i] = i;
  }

  long root(long x) {
    if (par[x] == x)
      return x;
    else
      root(par[x]);
  }

  void unite(long x, long y) {
    long rx = root(x);
    long ry = root(y);
    if (rx == ry)
      return;
    else
      par[rx] = ry;
  }

  bool same(long x, long y) {
    long rx = root(x);
    long ry = root(y);
    return rx == ry;
  }
};

int main() {
  long N, M;
  cin >> N >> M;
  long A[M], B[M];
  for (long i = 0; i < M; ++i) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  UnionFind tree(N);

  long ans[M];
  ans[M - 1] = N * (N - 1) / 2;
  map<long, long> size;

  for (long i = 0; i < N; ++i) {
    size[i] = 1;
  }

  for (long i = M - 1; i >= 0; --i) {
    if (!tree.same(A[i], B[i]) & i > 0) {
      ans[i - 1] = ans[i] - size[tree.root(A[i])] * size[tree.root(B[i])];
      long a = size[tree.root(A[i])];
      long b = size[tree.root(B[i])];
      size[tree.root(A[i])] += b;
      size[tree.root(B[i])] += a;
      if (b > a) {
        tree.unite(A[i], B[i]);
      } else {
        tree.unite(B[i], A[i]);
      }
    } else if (i > 0) {
      ans[i - 1] = ans[i];
    }
  }
  for (long i = 0; i < M; ++i) {
    cout << ans[i] << endl;
  }
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
using namespace std;
typedef long long ll;

struct UnionFind {
  vector<ll> link;
  UnionFind(ll n) : link(n, -1) {}
  ll find(ll v) {
    if (link[v] < 0)
      return v;
    else
      return link[v] = find(link[v]);
  }
  bool unite(ll v, ll w) {
    v = find(v), w = find(w);
    if (v == w)
      return 0;
    if (link[v] > link[w])
      swap(v, w);
    link[v] += link[w];
    link[w] = v;
    return 1;
  }
  bool same(ll v, ll w) { return find(v) == find(w); }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m), ans(m);
  rep(i, m) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  UnionFind uf(n);
  ans[m - 1] = n * (n - 1) / 2;
  for (ll i = m - 1; m >= 1; m--) {
    ans[i - 1] = ans[i] - uf.link[uf.find(a[i])] * uf.link[uf.find(b[i])];
    uf.unite(a[i], b[i]);
  }
  rep(i, m) cout << ans[i] << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
using namespace std;
typedef long long ll;

struct UnionFind {
  vector<ll> link;
  UnionFind(ll n) : link(n, -1) {}
  ll find(ll v) {
    if (link[v] < 0)
      return v;
    else
      return link[v] = find(link[v]);
  }
  bool unite(ll v, ll w) {
    v = find(v), w = find(w);
    if (v == w)
      return 0;
    if (link[v] > link[w])
      swap(v, w);
    link[v] += link[w];
    link[w] = v;
    return 1;
  }
  bool same(ll v, ll w) { return find(v) == find(w); }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m), ans(m);
  rep(i, m) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  UnionFind uf(n);
  ans[m - 1] = n * (n - 1) / 2;
  for (ll i = m - 1; i >= 1; i--) {
    if (uf.same(a[i], b[i]))
      ans[i - 1] = ans[i];
    else
      ans[i - 1] = ans[i] - uf.link[uf.find(a[i])] * uf.link[uf.find(b[i])];
    uf.unite(a[i], b[i]);
  }
  rep(i, m) cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
// ABC 120 D;
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 10010;
struct EDGE {
  int u, v;
} e[maxn];

ll sz[maxn], p[maxn], ans[maxn];

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}

int get_set(int x) {
  if (x != p[x])
    p[x] = get_set(p[x]);
  return p[x];
}

int main() {
  // freopen("","r",stdin);
  // freopen("","w",stdout);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    e[i].u = read();
    e[i].v = read();
  }
  ans[m] = (ll)(n - 1) * n / 2;
  for (int i = 1; i <= n; i++)
    p[i] = i, sz[i] = 1;
  for (int i = m; i >= 1; i--) {
    int u = get_set(e[i].u), v = get_set(e[i].v);
    if (u == v)
      ans[i - 1] = ans[i];
    else {
      ans[i - 1] = ans[i] - sz[u] * sz[v];
      p[u] = v;
      sz[v] += sz[u];
    }
  }
  for (int i = 1; i <= m; i++)
    cout << ans[i] << endl;
  return 0;
}

Fixed submission:
// ABC 120 D;
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 100010;
struct EDGE {
  int u, v;
} e[maxn];

ll sz[maxn], p[maxn], ans[maxn];

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}

int get_set(int x) {
  if (x != p[x])
    p[x] = get_set(p[x]);
  return p[x];
}

int main() {
  // freopen("","r",stdin);
  // freopen("","w",stdout);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    e[i].u = read();
    e[i].v = read();
  }
  ans[m] = (ll)(n - 1) * n / 2;
  for (int i = 1; i <= n; i++)
    p[i] = i, sz[i] = 1;
  for (int i = m; i >= 1; i--) {
    int u = get_set(e[i].u), v = get_set(e[i].v);
    if (u == v)
      ans[i - 1] = ans[i];
    else {
      ans[i - 1] = ans[i] - sz[u] * sz[v];
      p[u] = v;
      sz[v] += sz[u];
    }
  }
  for (int i = 1; i <= m; i++)
    cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

map<ll, ll> mp;

struct UnionFind {
  vector<ll> par; // par[i]:iの親の番号

  UnionFind(ll N) : par(N) { // 最初は全てが根であるとして初期化
    for (ll i = 0; i < N; i++)
      par[i] = i, mp[i]++;
  }

  ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  ll unite(ll x, ll y) { // xとyの木を併合
    ll rx = root(x);     // xの根をrx
    ll ry = root(y);     // yの根をry
    if (rx == ry)
      return 0; // xとyの根が同じ(=同じ木にある)時はそのまま
    else {
      ll sx = mp[rx], sy = mp[ry];
      par[rx] = ry;
      mp[ry] += mp[rx];
      ll s = mp[ry];
      return (s * (s - 1) - sx * (sx - 1) - sy * (sy - 1)) / 2;
    }
    // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m), ans(m);
  for (ll i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
  }
  UnionFind tree(n);
  ans[m - 1] = (n * (n - 1)) / 2;
  for (ll i = m - 1; i >= 1; i--) {
    ans[i - 1] = ans[i] - tree.unite(a[i], b[i]);
  }
  for (ll i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

map<ll, ll> mp;

struct UnionFind {
  vector<ll> par; // par[i]:iの親の番号

  UnionFind(ll N) : par(N) { // 最初は全てが根であるとして初期化
    for (ll i = 0; i < N; i++)
      par[i] = i, mp[i]++;
  }

  ll root(ll x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
    if (par[x] == x)
      return x;
    return par[x] = root(par[x]);
  }

  ll unite(ll x, ll y) { // xとyの木を併合
    ll rx = root(x);     // xの根をrx
    ll ry = root(y);     // yの根をry
    if (rx == ry)
      return 0; // xとyの根が同じ(=同じ木にある)時はそのまま
    else {
      ll sx = mp[rx], sy = mp[ry];
      par[rx] = ry;
      mp[ry] += mp[rx];
      ll s = mp[ry];
      return (s * (s - 1) - sx * (sx - 1) - sy * (sy - 1)) / 2;
    }
    // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m), ans(m);
  for (ll i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  UnionFind tree(n);
  ans[m - 1] = (n * (n - 1)) / 2;
  for (ll i = m - 1; i >= 1; i--) {
    ans[i - 1] = ans[i] - tree.unite(a[i], b[i]);
  }
  for (ll i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cerr << #x << ": " << x << endl
int main() {
  ll n, m;
  cin >> n >> m;
  vector<int> a(m), b(m);
  rep(i, m) {
    int na, nb;
    cin >> na >> nb;
    na--, nb--;
    a[i] = na;
    b[i] = nb;
  }
  vector<vector<int>> V(n);
  rep(j, n) V[j].push_back(j);
  vector<int> idx(n);
  rep(j, n) idx[j] = j;

  ll cnt = n * (n - 1) / 2; // take care not to be overflow
  vector<ll> ans;
  ans.push_back(cnt);

  reverse(all(a));
  reverse(all(b));

  rep(i, m - 1) {
    int aj = idx[a[i]], bj = idx[b[i]];
    if (aj == bj) {
      ans.push_back(cnt);
      continue;
    }

    ll sza = (ll)V[aj].size(), szb = (ll)V[bj].size();
    cnt -= sza * szb;
    ans.push_back(cnt);

    if (sza > szb)
      swap(aj, bj);
    for (auto x : V[bj]) {
      V[aj].push_back(x);
      idx[x] = aj;
    }
    V[bj].clear();
  }

  reverse(all(ans));
  rep(i, m) printf("%lld\n", ans[i]);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cerr << #x << ": " << x << endl
int main() {
  ll n, m;
  cin >> n >> m;
  vector<int> a(m), b(m);
  rep(i, m) {
    int na, nb;
    cin >> na >> nb;
    na--, nb--;
    a[i] = na;
    b[i] = nb;
  }
  vector<vector<int>> V(n);
  rep(j, n) V[j].push_back(j);
  vector<int> idx(n);
  rep(j, n) idx[j] = j;

  ll cnt = n * (n - 1) / 2; // take care not to be overflow
  vector<ll> ans;
  ans.push_back(cnt);

  reverse(all(a));
  reverse(all(b));

  rep(i, m - 1) {
    int aj = idx[a[i]], bj = idx[b[i]];
    if (aj == bj) {
      ans.push_back(cnt);
      continue;
    }

    ll sza = (ll)V[aj].size(), szb = (ll)V[bj].size();
    cnt -= sza * szb;
    ans.push_back(cnt);

    if (sza < szb)
      swap(aj, bj);
    for (auto x : V[bj]) {
      V[aj].push_back(x);
      idx[x] = aj;
    }
    V[bj].clear();
  }

  reverse(all(ans));
  rep(i, m) printf("%lld\n", ans[i]);
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cerr << #x << ": " << x << endl
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> a(m), b(m);
  rep(i, m) {
    int na, nb;
    cin >> na >> nb;
    na--, nb--;
    a[i] = na;
    b[i] = nb;
  }
  vector<set<int>> S(n);
  rep(i, n) S[i].emplace(i);
  vector<int> idx(n);
  rep(i, n) idx[i] = i;

  ll cnt = (ll)n * (n - 1) / 2; // take care not to be overflow
  vector<ll> ans;
  ans.push_back(cnt);

  reverse(all(a));
  reverse(all(b));

  rep(i, m - 1) {
    if (idx[a[i]] == idx[b[i]]) {
      ans.push_back(cnt);
      continue;
    }

    ll sza = (ll)S[idx[a[i]]].size();
    ll szb = (ll)S[idx[b[i]]].size();
    cnt -= sza * szb;
    ans.push_back(cnt);

    int addto = idx[a[i]];
    int removefrom = idx[b[i]];
    if (sza < szb) {
    } else {
      swap(addto, removefrom);
    }
    for (auto x : S[idx[removefrom]]) {
      S[idx[addto]].emplace(x);
      idx[x] = idx[addto];
    }
    S[removefrom].clear();
  }

  reverse(all(ans));
  rep(i, m) printf("%lld\n", ans[i]);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cerr << #x << ": " << x << endl
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> a(m), b(m);
  rep(i, m) {
    int na, nb;
    cin >> na >> nb;
    na--, nb--;
    a[i] = na;
    b[i] = nb;
  }
  vector<set<int>> S(n);
  rep(i, n) S[i].emplace(i);
  vector<int> idx(n);
  rep(i, n) idx[i] = i;

  ll cnt = (ll)n * (n - 1) / 2; // take care not to be overflow
  vector<ll> ans;
  ans.push_back(cnt);

  reverse(all(a));
  reverse(all(b));

  rep(i, m - 1) {
    if (idx[a[i]] == idx[b[i]]) {
      ans.push_back(cnt);
      continue;
    }

    ll sza = (ll)S[idx[a[i]]].size();
    ll szb = (ll)S[idx[b[i]]].size();
    cnt -= sza * szb;
    ans.push_back(cnt);

    int addto = idx[a[i]];
    int removefrom = idx[b[i]];
    if (sza < szb) {
      swap(addto, removefrom);
    }
    for (auto x : S[idx[removefrom]]) {
      S[idx[addto]].emplace(x);
      idx[x] = idx[addto];
    }
    S[removefrom].clear();
  }

  reverse(all(ans));
  rep(i, m) printf("%lld\n", ans[i]);
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;

const int maxN = 150010;
const int MAXM = 310;
const int MAXK = 17;
const int MOD = 1000000007;
const ll INF = 10000000000000000LL;
const ll inf = 5000000000000LL;

int father[maxN];
int find(int x) {
  if (x == father[x])
    return x;
  else
    return find(father[x]);
}
ll size[maxN];
int n, m;
int X[maxN], Y[maxN];
ll ans[maxN];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &X[i], &Y[i]);
  }
  for (int i = 1; i <= n; i++) {
    father[i] = i;
    size[i] = 1ll;
  }
  ans[m] = (ll)(n - 1) * n / 2;
  for (int i = m; i > 1; i--) {
    int u = find(X[i]);
    int v = find(Y[i]);
    if (u != v) {
      ll tmp = size[u] * size[v];
      ans[i - 1] = ans[i] - tmp;
      father[u] = v;
      size[v] += size[u];
    } else
      ans[i - 1] = ans[i];
  }
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;

const int maxN = 150010;
const int MAXM = 310;
const int MAXK = 17;
const int MOD = 1000000007;
const ll INF = 10000000000000000LL;
const ll inf = 5000000000000LL;

int father[maxN];
int find(int x) {
  if (x == father[x])
    return x;
  else
    return father[x] = find(father[x]);
}
ll size[maxN];
int n, m;
int X[maxN], Y[maxN];
ll ans[maxN];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &X[i], &Y[i]);
  }
  for (int i = 1; i <= n; i++) {
    father[i] = i;
    size[i] = 1ll;
  }
  ans[m] = (ll)(n - 1) * n / 2;
  for (int i = m; i > 1; i--) {
    int u = find(X[i]);
    int v = find(Y[i]);
    if (u != v) {
      ll tmp = size[u] * size[v];
      ans[i - 1] = ans[i] - tmp;
      father[u] = v;
      size[v] += size[u];
    } else
      ans[i - 1] = ans[i];
  }
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  UnionFind(size_t size) : v(size, -1) {}
  vector<int> v;

  int root(int x) { return (v[x] < 0 ? x : v[x] = root(v[x])); }

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (v[x] > v[y])
        swap(x, y);
      v[x] += v[y];
      v[y] = x;
    }
  }

  int count(int x) { return -v[root(x)]; }
};

int main() {
  int N, M;
  cin >> N >> M;

  vector<int> a(M), b(M);
  for (int i = 0; i < M; ++i)
    cin >> a[i] >> b[i];

  UnionFind uf(N);
  vector<int64_t> ans(M);
  for (int i = M - 1; i >= 0; --i) {
    if (!uf.same(a[i], b[i])) {
      ans[i] = 1ll * uf.count(a[i]) * uf.count(b[i]);
    }

    uf.unite(a[i], b[i]);
  }

  for (int i = 1; i < M; ++i) {
    ans[i] += ans[i - 1];
  }

  for (auto i : ans)
    cout << i << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

struct UnionFind {
  UnionFind(size_t size) : v(size, -1) {}
  vector<int> v;

  int root(int x) { return (v[x] < 0 ? x : v[x] = root(v[x])); }

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (v[x] > v[y])
        swap(x, y);
      v[x] += v[y];
      v[y] = x;
    }
  }

  int count(int x) { return -v[root(x)]; }
};

int main() {
  int N, M;
  cin >> N >> M;

  vector<int> a(M), b(M);
  for (int i = 0; i < M; ++i)
    cin >> a[i] >> b[i];

  UnionFind uf(N + 1);
  vector<int64_t> ans(M);
  for (int i = M - 1; i >= 0; --i) {
    if (!uf.same(a[i], b[i])) {
      ans[i] = 1ll * uf.count(a[i]) * uf.count(b[i]);
    }

    uf.unite(a[i], b[i]);
  }

  for (int i = 1; i < M; ++i) {
    ans[i] += ans[i - 1];
  }

  for (auto i : ans)
    cout << i << endl;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <string.h>

#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) ((a < b) ? (a) : (b))

using namespace std;

long N, M;
long *a, *b;
long *ans;

class nodeClass {
public:
  nodeClass() {
    next = NULL;
    num = 0;
  }

  nodeClass *next;
  int id;
  int num;
};

nodeClass *np;

nodeClass *getNode(int i) {
  nodeClass *node = &np[i];
  while (node->next != NULL) {
    node = node->next;
  }
  return node;
}

int main() {
  cin >> N >> M;
  a = new long[M];
  b = new long[M];
  ans = new long[M];
  np = new nodeClass[N];

  ans[M - 1] = (N * (N - 1)) / 2;

  for (int i = 0; i < N; i++) {
    np[i].num = 1;
    np[i].id = i;
  }
  for (int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }

  for (int k = M - 1; k > 0; k--) {
    int x = a[k], y = b[k];
    nodeClass *nx = getNode(x), *ny = getNode(y);
    if (nx->id == ny->id) {
      ans[k - 1] = ans[k];
    } else {
      ans[k - 1] = ans[k] - nx->num * ny->num;
      nodeClass *node = new nodeClass;
      node->id = N + M - k;
      node->num = nx->num + ny->num;
      nx->next = node;
      ny->next = node;
    }
  }

  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}

Fixed submission:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <string.h>

#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) ((a < b) ? (a) : (b))

using namespace std;

long N, M;
long *a, *b;
long *ans;

class nodeClass {
public:
  nodeClass() {
    next = NULL;
    num = 0;
  }

  nodeClass *next;
  int id;
  int num;
};

nodeClass *np;

nodeClass *getNode(int i) {
  nodeClass *node = &np[i];
  while (node->next != NULL) {
    node = node->next;
  }
  return node;
}

int main() {
  cin >> N >> M;
  a = new long[M];
  b = new long[M];
  ans = new long[M];
  np = new nodeClass[N];

  ans[M - 1] = (N * (N - 1)) / 2;

  for (int i = 0; i < N; i++) {
    np[i].num = 1;
    np[i].id = i;
  }
  for (int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }

  for (int k = M - 1; k > 0; k--) {
    int x = a[k], y = b[k];
    nodeClass *nx = getNode(x), *ny = getNode(y);
    if (nx->id == ny->id) {
      ans[k - 1] = ans[k];
    } else {
      ans[k - 1] = ans[k] - nx->num * ny->num;
      nodeClass *node = new nodeClass;
      node->id = N + M - k;
      node->num = nx->num + ny->num;
      nx->next = node;
      ny->next = node;
      np[x].next = node;
      np[y].next = node;
    }
  }

  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Unionfind {
public:
  vector<int> oya;
  Unionfind(int N) { oya = vector<int>(N, -1); }

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

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

  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (size(x) < size(y))
      swap(x, y);
    oya[x] += oya[y];
    oya[y] = x;
    return true;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> a(M), b(M);
  for (int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  vector<long long> ans(M);
  ans[M - 1] = (long long)N * (N - 1) / 2;

  Unionfind island(N);

  for (int i = M - 1; i >= 0; i--) {
    if (island.root(a[i]) != island.root(b[i])) {
      ans[i - 1] = ans[i] - (long long)island.size(a[i]) * island.size(b[i]);
      island.unite(a[i], b[i]);
    } else
      ans[i - 1] = ans[i];
  }

  for (int i = 0; i < M; i++)
    cout << ans[i] << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Unionfind {
public:
  vector<int> oya;
  Unionfind(int N) { oya = vector<int>(N, -1); }

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

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

  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    if (size(x) < size(y))
      swap(x, y);
    oya[x] += oya[y];
    oya[y] = x;
    return true;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> a(M), b(M);
  for (int i = 0; i < M; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  vector<long long> ans(M);
  ans[M - 1] = (long long)N * (N - 1) / 2;

  Unionfind island(N);

  for (int i = M - 1; i >= 1; i--) {
    if (island.root(a[i]) != island.root(b[i])) {
      ans[i - 1] = ans[i] - (long long)island.size(a[i]) * island.size(b[i]);
      island.unite(a[i], b[i]);
    } else
      ans[i - 1] = ans[i];
  }

  for (int i = 0; i < M; i++)
    cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int n, m;
int par[20005];
int num[20005];
pair<int, int> e1[10005];
long long ans[10005];
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
long long unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return 0;
  long long xn = num[x], yn = num[y];
  par[y] = x;
  num[x] += num[y];
  return xn * yn;
}
int main() {
  cin >> n >> m;
  long long N = (long long)n * (long long)(n - 1) / (long long)2;
  for (int i = 0; i < n; i++) {
    par[i] = i;
    num[i] = (long long)1;
  }
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    e1[i] = make_pair(x, y);
  }
  ans[m] = N;
  for (int i = m - 1; i >= 0; i--) {
    int x = e1[i].first;
    int y = e1[i].second;
    ans[i] = ans[i + 1] - unite(x, y);
  }
  for (int i = 1; i <= m; i++)
    cout << ans[i] << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
int n, m;
int par[200005];
int num[200005];
pair<int, int> e1[100005];
long long ans[100005];
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
long long unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return 0;
  long long xn = num[x], yn = num[y];
  par[y] = x;
  num[x] += num[y];
  return xn * yn;
}
int main() {
  cin >> n >> m;
  long long N = (long long)n * (long long)(n - 1) / (long long)2;
  for (int i = 0; i < n; i++) {
    par[i] = i;
    num[i] = (long long)1;
  }
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    e1[i] = make_pair(x, y);
  }
  ans[m] = N;
  for (int i = m - 1; i >= 0; i--) {
    int x = e1[i].first;
    int y = e1[i].second;
    ans[i] = ans[i + 1] - unite(x, y);
  }
  for (int i = 1; i <= m; i++)
    cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define repl(i, x, n)                                                          \
  for (long long i = (long long)(x); i < (long long)(n); i++)
#define rep(i, x, n) for (long i = long(x); i < long(n); i++)
long id[100009];
map<long, long> q;
vector<pair<long, long>> v;
void init(long n) {
  rep(i, 0, n + 1) {
    id[i] = i;
    q[i] = 1;
  }
}
long root(long x) {
  while (id[x] != x)
    x = id[x];
  return x;
}
void Union(long x, long y) { id[root(x)] = id[root(y)]; }
long long CC(long long x) { return ((x) * (x - 1)) / 2; }
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long n, m, x, y;
  long long c = 0, a, b;
  vector<long long> ans;
  cin >> n >> m;
  ans.push_back(CC(n));
  // cout<<"0\n";
  init(n);
  rep(i, 0, m) {
    cin >> x >> y;
    v.push_back({x, y});
  }
  for (long i = m - 1; i >= 0; i--) {
    // cout<<v[i].first<<" "<<v[i].second<<"\n";
    x = v[i].first;
    y = v[i].second;
    if (root(x) != root(y)) {
      a = q[root(x)];
      b = q[root(y)];
      q[root(x)] += b;
      q[root(y)] += a;
      c -= CC(a);
      c -= CC(b);
      c += CC(a + b);
    }
    ans.push_back(CC(n) - c);
    // cout<<c<<"\n";
    Union(x, y);
    // rep(j,1,n+1)
    //     cout<<j<<" "<<id[j]<<"\n";
    // cout<<"\n";
  }
  // cout<<"\n";
  for (long i = m - 1; i >= 0; --i)
    cout << ans[i] << "\n";
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define repl(i, x, n)                                                          \
  for (long long i = (long long)(x); i < (long long)(n); i++)
#define rep(i, x, n) for (long i = long(x); i < long(n); i++)
long id[100009];
map<long, long> q;
vector<pair<long, long>> v;
void init(long n) {
  rep(i, 0, n + 1) {
    id[i] = i;
    q[i] = 1;
  }
}
long root(long x) {
  while (id[x] != x)
    x = id[x];
  return x;
}
void Union(long x, long y) { id[root(x)] = id[root(y)]; }
long long CC(long long x) { return ((x) * (x - 1)) / 2; }
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long n, m, x, y;
  long long c = 0, a, b;
  vector<long long> ans;
  cin >> n >> m;
  ans.push_back(CC(n));
  // cout<<"0\n";
  init(n);
  rep(i, 0, m) {
    cin >> x >> y;
    v.push_back({x, y});
  }
  for (long i = m - 1; i >= 0; i--) {
    // cout<<v[i].first<<" "<<v[i].second<<"\n";
    x = v[i].first;
    y = v[i].second;
    if (root(x) != root(y)) {
      a = q[root(x)];
      b = q[root(y)];
      q[root(x)] += b;
      q[root(y)] += a;
      c -= CC(a);
      c -= CC(b);
      c += CC(a + b);
    }
    ans.push_back(CC(n) - c);
    // cout<<c<<"\n";
    Union(x, y);
    id[x] = root(x);
    id[y] = root(y);
    // rep(j,1,n+1)
    //     cout<<j<<" "<<id[j]<<"\n";
    // cout<<"\n";
  }
  // cout<<"\n";
  for (long i = m - 1; i >= 0; --i)
    cout << ans[i] << "\n";
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

class UnionFind {
public:
  // 親の番号を格納、親だった場合は-(その集合のサイズ)
  vector<int> Parent;

  // 親初期化（N個の要素すべてに-1を代入）
  UnionFind(int N) { Parent = vector<int>(N, -1); }

  // Aがどのグループに属しているか調べる
  int root(int A) {
    if (Parent[A] < 0)
      return A;
    return Parent[A] = root(Parent[A]);
  }

  // 自分のいるグループの頂点数を調べる
  int size(int A) { return -Parent[root(A)]; }

  // AとBをくっ付ける
  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;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(M), B(M);
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  vector<long long> ans(M);
  ans[M - 1] = (long long)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] -= (long long)Uni.size(A[i]) * Uni.size(B[i]);
      Uni.connect(A[i], B[i]);
    }
  }

  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

class UnionFind {
public:
  // 親の番号を格納、親だった場合は-(その集合のサイズ)
  vector<int> Parent;

  // 親初期化（N個の要素すべてに-1を代入）
  UnionFind(int N) { Parent = vector<int>(N, -1); }

  // Aがどのグループに属しているか調べる
  int root(int A) {
    if (Parent[A] < 0)
      return A;
    return Parent[A] = root(Parent[A]);
  }

  // 自分のいるグループの頂点数を調べる
  int size(int A) { return -Parent[root(A)]; }

  // AとBをくっ付ける
  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;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(M), B(M);
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  vector<long long> ans(M);
  ans[M - 1] = (long long)N * (N - 1) / 2;

  UnionFind Uni(N);

  for (int i = M - 1; i >= 1; i--) {

    ans[i - 1] = ans[i];

    // 繋がってないのがつながったとき
    if (Uni.root(A[i]) != Uni.root(B[i])) {
      ans[i - 1] -= (long long)Uni.size(A[i]) * Uni.size(B[i]);
      Uni.connect(A[i], B[i]);
    }
  }

  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
}