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

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
int a[100010], b[100010], father[100010];
long long n, m, ans[100010], sum[100010];
int find_father(int x) {
  while (father[x] != x)
    x = father[x];
  return x;
}
int main() {
  int i, x, y;
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    father[i] = i;
    sum[i] = 1;
  }
  for (i = 1; i <= m; i++)
    cin >> a[i] >> b[i];
  ans[m] = n * (n - 1) / 2;
  for (i = m; i >= 2; i--) {
    x = find_father(a[i]);
    y = find_father(b[i]);
    if (x != y) {
      ans[i - 1] = ans[i] - sum[x] * sum[y];
      sum[x] += sum[y];
      father[y] = x;
    } else
      ans[i - 1] = ans[i];
  }
  for (i = 1; i <= m; i++)
    cout << ans[i] << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
int a[100010], b[100010], father[100010];
long long n, m, ans[100010], sum[100010];
int find_father(int x) {
  while (father[x] != x)
    x = father[x];
  return x;
}
int main() {
  int i, x, y;
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    father[i] = i;
    sum[i] = 1;
  }
  for (i = 1; i <= m; i++)
    cin >> a[i] >> b[i];
  ans[m] = n * (n - 1) / 2;
  for (i = m; i >= 2; i--) {
    x = find_father(a[i]);
    y = find_father(b[i]);
    father[a[i]] = x;
    father[b[i]] = x;
    if (x != y) {
      ans[i - 1] = ans[i] - sum[x] * sum[y];
      sum[x] += sum[y];
      father[y] = x;
    } else
      ans[i - 1] = ans[i];
  }
  for (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;
using ll = long long;

struct UnionFind {
  vector<ll> rnk, par, num;
  UnionFind(ll N) : rnk(N), par(N), num(N) { init(); }
  void init() {
    for (ll i = 0; i < rnk.size(); i++) {
      rnk[i] = 0;
      par[i] = i;
      num[i] = 1;
    }
  }
  ll find(ll x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  void unite(ll x, ll y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
      num[y] += num[x];
    } else {
      par[y] = x;
      num[x] += num[y];
      if (rnk[x] == rnk[y])
        rnk[x]++;
    }
  }
  bool same(ll x, ll y) { return (find(x) == find(y)); }
  ll size(ll x) { return num[find(x)]; }
};

signed main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m);
  for (int i = 0; i < m; i++) {
    scanf("ll%d%lld", &a[i], &b[i]);
    --a[i];
    --b[i];
  }
  UnionFind tree(n);
  vector<ll> ans;
  ll num = n * (n - 1) / 2;
  ans.push_back(num);
  for (ll i = m - 1; i >= 1; i--) {
    ll x = a[i], y = b[i];
    if (!tree.same(x, y)) {
      num -= tree.size(x) * tree.size(y);
      tree.unite(x, y);
    }
    ans.push_back(num);
  }
  reverse(ans.begin(), ans.end());
  for (ll i : ans)
    cout << i << '\n';
}


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

struct UnionFind {
  vector<ll> rnk, par, num;
  UnionFind(ll N) : rnk(N), par(N), num(N) { init(); }
  void init() {
    for (ll i = 0; i < rnk.size(); i++) {
      rnk[i] = 0;
      par[i] = i;
      num[i] = 1;
    }
  }
  ll find(ll x) {
    if (par[x] == x)
      return x;
    return par[x] = find(par[x]);
  }
  void unite(ll x, ll y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
      num[y] += num[x];
    } else {
      par[y] = x;
      num[x] += num[y];
      if (rnk[x] == rnk[y])
        rnk[x]++;
    }
  }
  bool same(ll x, ll y) { return (find(x) == find(y)); }
  ll size(ll x) { return num[find(x)]; }
};

signed main() {
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m);
  for (int i = 0; i < m; i++) {
    scanf("%lld%lld", &a[i], &b[i]);
    --a[i];
    --b[i];
  }
  UnionFind tree(n);
  vector<ll> ans;
  ll num = n * (n - 1) / 2;
  ans.push_back(num);
  for (ll i = m - 1; i >= 1; i--) {
    ll x = a[i], y = b[i];
    if (!tree.same(x, y)) {
      num -= tree.size(x) * tree.size(y);
      tree.unite(x, y);
    }
    ans.push_back(num);
  }
  reverse(ans.begin(), ans.end());
  for (ll i : ans)
    cout << i << '\n';
}
Problem p03108 (C++)

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

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

  // 作るときはParentの値を全て-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とBを直接つなぐのではなく、root(A)にroot(B)をくっつける
    A = root(A);
    B = root(B);
    if (A == B) {
      // すでにくっついてるからくっ付けない
      return false;
    }

    // 大きい方(A)に小さいほう(B)をくっ付けたい
    // 大小が逆だったらひっくり返しちゃう。
    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];
  }

  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;
  }
}


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

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

  // 作るときはParentの値を全て-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とBを直接つなぐのではなく、root(A)にroot(B)をくっつける
    A = root(A);
    B = root(B);
    if (A == B) {
      // すでにくっついてるからくっ付けない
      return false;
    }

    // 大きい方(A)に小さいほう(B)をくっ付けたい
    // 大小が逆だったらひっくり返しちゃう。
    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 >= 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;
  }
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef long long ll;

class UnionFind {
private:
  vector<ll> data;

public:
  UnionFind(ll n) : data(n, -1) {}

  ll size(ll i) { return -data[find(i)]; }
  bool root(ll i) { return data[i] < 0; }
  bool same(ll i, ll j) { return find(i) == find(j); }

  ll find(ll i) { return root(i) ? i : (data[i] = find(data[i])); }

  bool unite(ll i, ll j) {
    if (same(i, j))
      return false;
    data[find(i)] += data[find(j)];
    data[find(j)] = find(i);
    return true;
  }
};

int main(void) {
  ll N, M;
  cin >> N >> M;
  vector<ll> A(M), B(M);
  REP(i, 0, M) cin >> A[i] >> B[i];

  UnionFind uf(N);
  vector<ll> ans(M);
  ll x = N * (N - 1) / 2;
  for (ll i = M - 1; i >= 0; i--) {
    ans[i] = x;
    if (!uf.same(A[i], B[i])) {
      x -= uf.size(A[i]) * uf.size(B[i]);
      uf.unite(A[i], B[i]);
    }
  }

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

Fixed submission:
#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll)a); i < ((ll)n); i++)
using namespace std;
typedef long long ll;

class UnionFind {
private:
  vector<ll> data;

public:
  UnionFind(ll n) : data(n, -1) {}

  ll size(ll i) { return -data[find(i)]; }
  bool root(ll i) { return data[i] < 0; }
  bool same(ll i, ll j) { return find(i) == find(j); }

  ll find(ll i) { return root(i) ? i : (data[i] = find(data[i])); }

  bool unite(ll i, ll j) {
    if (same(i, j))
      return false;
    data[find(i)] += data[find(j)];
    data[find(j)] = find(i);
    return true;
  }
};

int main(void) {
  ll N, M;
  cin >> N >> M;
  vector<ll> A(M), B(M);
  REP(i, 0, M) cin >> A[i] >> B[i], A[i]--, B[i]--;

  UnionFind uf(N);
  vector<ll> ans(M);
  ll x = N * (N - 1) / 2;
  for (ll i = M - 1; i >= 0; i--) {
    ans[i] = x;
    if (!uf.same(A[i], B[i])) {
      x -= uf.size(A[i]) * uf.size(B[i]);
      uf.unite(A[i], B[i]);
    }
  }

  REP(i, 0, M) cout << ans[i] << endl;
}
Problem p03108 (C++)

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

ll n, m;
ll a[11111];
ll b[11111];
ll res[11111];

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(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);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

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

int main() {
  cin >> n >> m;
  for (ll i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  UnionFind tree(n);
  res[m] = n * (n - 1) / 2;
  for (ll i = m - 1; i >= 0; i--) {
    if (tree.issame(a[i], b[i])) {
      res[i] = res[i + 1];
    } else {
      res[i] = res[i + 1] - (tree.size(a[i]) * tree.size(b[i]));
    }
    tree.merge(a[i], b[i]);
  }
  for (ll i = 1; i <= m; i++) {
    cout << res[i] << endl;
  }
  return 0;
}


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

ll n, m;
ll a[111111];
ll b[111111];
ll res[111111];

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(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);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

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

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

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 1 << 30;
const int MOD = 1e9 + 7;
const int dy[] = {1, 0, -1, 0};
const int dx[] = {0, 1, 0, -1};
template <class Type> class UnionFind {
public:
  vector<Type> data;
  UnionFind(int sz) { data.assign(sz, -1); }
  bool unite(Type x, Type y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }
  Type find(Type k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }
  Type size(Type k) { return (-data[find(k)]); }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, m;
  cin >> n >> m;
  vector<ll> a(n), b(n);
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  ll cnt = (n * n - n) / 2;
  UnionFind<ll> uf(n + 1);
  vector<ll> ans;
  for (int i = m - 1; i >= 0; i--) {
    ans.push_back(cnt);
    if (uf.find(a[i]) == uf.find(b[i]))
      continue;
    cnt -= uf.size(a[i]) * uf.size(b[i]);
    uf.unite(a[i], b[i]);
  }
  reverse(ans.begin(), ans.end());
  for (int i = 0; i < ans.size(); i++)
    cout << ans[i] << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <string>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
const int INF = 1 << 30;
const int MOD = 1e9 + 7;
const int dy[] = {1, 0, -1, 0};
const int dx[] = {0, 1, 0, -1};
template <class Type> class UnionFind {
public:
  vector<Type> data;
  UnionFind(int sz) { data.assign(sz, -1); }
  bool unite(Type x, Type y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }
  Type find(Type k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }
  Type size(Type k) { return (-data[find(k)]); }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  ll n, m;
  cin >> n >> m;
  vector<ll> a(m), b(m);
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  ll cnt = (n * n - n) / 2;
  UnionFind<ll> uf(n + 1);
  vector<ll> ans;
  for (int i = m - 1; i >= 0; i--) {
    ans.push_back(cnt);
    if (uf.find(a[i]) == uf.find(b[i]))
      continue;
    cnt -= uf.size(a[i]) * uf.size(b[i]);
    uf.unite(a[i], b[i]);
  }
  reverse(ans.begin(), ans.end());
  for (int i = 0; i < ans.size(); i++)
    cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define RANGE(i, n) for (int i = 0; i < n; i++)
typedef long long ll;

using namespace std;

struct union_find {
  vector<ll> par;
  vector<ll> size;

  union_find(ll n) : par(n), size(n) {
    RANGE(i, n) {
      par[i] = i;
      size[i] = 1;
    }
  }

  void union_tree(ll i, ll j) {
    ll root_i = root(i);
    ll root_j = root(j);
    par[root_i] = root_j;
    size[root_j] = size[root_i] + size[root_j];
  }

  ll root(ll i) {
    if (par[i] == i)
      return i;
    else
      root(par[i]);
  }

  bool same(ll i, ll j) { return root(i) == root(j); }

  ll get_size(ll i) { return size[root(i)]; }
};

signed main() {
  ll N, M;
  cin >> N >> M;
  ll A[M];
  ll B[M];
  RANGE(i, M) {
    ll x, y;
    cin >> x >> y;
    A[i] = x - 1;
    B[i] = y - 1;
  }
  ll unconf = (N - 1) * N / 2;
  stack<ll> result;
  union_find tree(N);
  for (ll i = M - 1; i > -1; i--) {
    result.push(unconf);
    if (!tree.same(A[i], B[i])) {
      ll a_size = tree.get_size(A[i]);
      ll b_size = tree.get_size(B[i]);
      unconf -= a_size * b_size;
      tree.union_tree(A[i], B[i]);
    }
  }
  while (!result.empty()) {
    cout << result.top() << endl;
    result.pop();
  }
}


Fixed submission:
#include <bits/stdc++.h>
#define RANGE(i, n) for (int i = 0; i < n; i++)
typedef long long ll;

using namespace std;

struct union_find {
  vector<ll> par;
  vector<ll> size;

  union_find(ll n) : par(n), size(n) {
    RANGE(i, n) {
      par[i] = i;
      size[i] = 1;
    }
  }

  void union_tree(ll i, ll j) {
    ll root_i = root(i);
    ll root_j = root(j);
    par[root_i] = root_j;
    size[root_j] = size[root_i] + size[root_j];
  }

  ll root(ll i) {
    ll now = i;
    vector<ll> on_route;
    while (par[now] != now) {
      on_route.push_back(now);
      now = par[now];
    }
    for (ll node : on_route)
      par[node] = now;
    return now;
  }

  bool same(ll i, ll j) { return root(i) == root(j); }

  ll get_size(ll i) { return size[root(i)]; }
};

signed main() {
  ll N, M;
  cin >> N >> M;
  ll A[M];
  ll B[M];
  RANGE(i, M) {
    ll x, y;
    cin >> x >> y;
    A[i] = x - 1;
    B[i] = y - 1;
  }
  ll unconf = (N - 1) * N / 2;
  stack<ll> result;
  union_find tree(N);
  for (ll i = M - 1; i > -1; i--) {
    result.push(unconf);
    if (!tree.same(A[i], B[i])) {
      ll a_size = tree.get_size(A[i]);
      ll b_size = tree.get_size(B[i]);
      unconf -= a_size * b_size;
      tree.union_tree(A[i], B[i]);
    }
  }
  while (!result.empty()) {
    cout << result.top() << endl;
    result.pop();
  }
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define ve vector

struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int find(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -d[find(x)]; }
};

int main() {
  ll n, m;
  cin >> n >> m;
  ve<P> e(m);
  ve<ll> ans(m);
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    e[i] = P(a, b);
  }
  reverse(e.begin(), e.end());
  ans[0] = (n - 1) * n / 2;
  UnionFind uf(n);
  rep(i, m) {
    if (uf.same(e[i].first, e[i].second))
      ans[i + 1] = ans[i];
    else
      ans[i + 1] = ans[i] - uf.size(e[i].first) * uf.size(e[i].second);
    uf.unite(e[i].first, e[i].second);
  }
  reverse(ans.begin(), ans.end());
  rep(i, m) cout << ans[i] << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define ve vector

struct UnionFind {
  vector<int> d;
  UnionFind(int n = 0) : d(n, -1) {}
  int find(int x) {
    if (d[x] < 0)
      return x;
    return d[x] = find(d[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (d[x] > d[y])
      swap(x, y);
    d[x] += d[y];
    d[y] = x;
    return true;
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -d[find(x)]; }
};

int main() {
  ll n, m;
  cin >> n >> m;
  ve<P> e(m);
  ve<ll> ans(m);
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    e[i] = P(a, b);
  }
  reverse(e.begin(), e.end());
  ans[0] = (n - 1) * n / 2;
  UnionFind uf(n);
  rep(i, m - 1) {
    if (uf.same(e[i].first, e[i].second))
      ans[i + 1] = ans[i];
    else
      ans[i + 1] = ans[i] - uf.size(e[i].first) * uf.size(e[i].second);
    uf.unite(e[i].first, e[i].second);
  }
  reverse(ans.begin(), ans.end());
  rep(i, m) cout << ans[i] << endl;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
typedef long long ll;
typedef pair<int, int> pint;
typedef pair<ll, int> pli;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y]) {
      par[y] += par[x];
      par[x] = y;
    } else {
      par[x] += par[y];
      par[y] = x;
    }
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  ll size(int x) { return -par[find(x)]; }
};
int main() {
  ll n, m;
  cin >> n >> m;
  vector<pint> p(m);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    p[m - i - 1] = {x, y};
  }
  UnionFind uf(n);
  vector<ll> ans(m);
  ans[0] = n * (n - 1) / 2;
  rep(i, m) {
    ans[i + 1] = ans[i] - uf.size(p[i].first) * uf.size(p[i].second);
    uf.unite(p[i].first, p[i].second);
  }
  rep(i, m) cout << ans[m - i - 1] << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
typedef long long ll;
typedef pair<int, int> pint;
typedef pair<ll, int> pli;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  int find(int x) {
    if (par[x] < 0)
      return x;
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return false;
    if (par[x] > par[y]) {
      par[y] += par[x];
      par[x] = y;
    } else {
      par[x] += par[y];
      par[y] = x;
    }
    return true;
  }

  bool same(int x, int y) { return find(x) == find(y); }
  ll size(int x) { return -par[find(x)]; }
};
int main() {
  ll n, m;
  cin >> n >> m;
  vector<pint> p(m);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    p[m - i - 1] = {x, y};
  }
  UnionFind uf(n);
  vector<ll> ans(m);
  ans[0] = n * (n - 1) / 2;
  rep(i, m - 1) {
    if (!uf.same(p[i].first, p[i].second))
      ans[i + 1] = ans[i] - uf.size(p[i].first) * uf.size(p[i].second);
    else
      ans[i + 1] = ans[i];
    uf.unite(p[i].first, p[i].second);
  }
  rep(i, m) cout << ans[m - i - 1] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int N_MAX = 100001;
typedef pair<int, int> P;
int main() {
  long long n, m;
  cin >> n >> m;
  P b[N_MAX];
  int c[N_MAX], nc[N_MAX], pc[N_MAX], pi[N_MAX];
  long long res[N_MAX];
  int i1, i2, s1, s2, p, pt;
  long long c1, c2;
  for (int i = 0; i < m; i++)
    cin >> b[i].first >> b[i].second;
  for (int i = 1; i <= n; i++) {
    c[i] = i;
    nc[i] = 1;
    pc[i] = i;
    pi[i] = 0;
  }
  res[m - 1] = n * (n - 1) / 2;
  for (int i = m - 1; i > 0; i--) {
    i1 = b[i].first;
    i2 = b[i].second;
    if (c[i1] == c[i2])
      res[i - 1] = res[i];
    else {
      s1 = c[i1];
      s2 = c[i2];
      res[i - 1] = res[i] - nc[s1] * nc[s2];
      pt = pc[s1];
      p = pc[s2];
      pc[s1] = p;
      nc[s1] += nc[s2];
      pc[s2] = 0;
      nc[s2] = 0;
      while (true) {
        c[p] = s1;
        if (pi[p] == 0)
          break;
        p = pi[p];
      }
      pi[p] = pt;
    }
  }
  for (int i = 0; i < m; i++)
    cout << res[i] << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int N_MAX = 100001;
typedef pair<int, int> P;
int main() {
  long long n, m;
  cin >> n >> m;
  P b[N_MAX];
  int c[N_MAX], nc[N_MAX], pc[N_MAX], pi[N_MAX];
  long long res[N_MAX];
  int i1, i2, s1, s2, p, pt;
  long long c1, c2;
  for (int i = 0; i < m; i++)
    cin >> b[i].first >> b[i].second;
  for (int i = 1; i <= n; i++) {
    c[i] = i;
    nc[i] = 1;
    pc[i] = i;
    pi[i] = 0;
  }
  res[m - 1] = n * (n - 1) / 2;
  for (int i = m - 1; i > 0; i--) {
    i1 = b[i].first;
    i2 = b[i].second;
    if (c[i1] == c[i2])
      res[i - 1] = res[i];
    else {
      s1 = c[i1];
      s2 = c[i2];
      if (nc[s1] < nc[s2]) {
        s1 = c[i2];
        s2 = c[i1];
      }
      res[i - 1] = res[i] - nc[s1] * nc[s2];
      pt = pc[s1];
      p = pc[s2];
      pc[s1] = p;
      nc[s1] += nc[s2];
      pc[s2] = 0;
      nc[s2] = 0;
      while (true) {
        c[p] = s1;
        if (pi[p] == 0)
          break;
        p = pi[p];
      }
      pi[p] = pt;
    }
  }
  for (int i = 0; i < m; i++)
    cout << res[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
long long n, m;
long long f[10001], yh[10001];
long long bb(long long p) {
  if (f[p] == p)
    return p;
  return f[p] = bb(f[p]);
}
int main() {
  cin >> n >> m;
  long long i, x[m + 1], y[m + 1], ans[m], j, k, s, z = n;
  for (i = 1; i <= n; i++) {
    f[i] = i;
    yh[i] = 1;
  }
  for (i = 1; i <= m; i++)
    cin >> x[i] >> y[i];
  long long jk = ans[m - 1] = n * (n - 1) / 2;
  for (i = m; i > 0; i--) {
    long long zux = bb(x[i]), zuy = bb(y[i]);
    if (zux != zuy) {
      f[zux] = zuy;
      jk -= yh[zux] * yh[zuy];
      yh[zuy] += yh[zux];
    }
    ans[i - 2] = jk;
  }
  for (i = 0; i < m; i++)
    cout << ans[i] << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
long long n, m;
long long f[100010], yh[100010];
long long bb(long long p) {
  if (f[p] == p)
    return p;
  return f[p] = bb(f[p]);
}
int main() {
  cin >> n >> m;
  long long i, x[m + 1], y[m + 1], ans[m], j, k, s, z = n;
  for (i = 1; i <= n; i++) {
    f[i] = i;
    yh[i] = 1;
  }
  for (i = 1; i <= m; i++)
    cin >> x[i] >> y[i];
  long long jk = ans[m - 1] = n * (n - 1) / 2;
  for (i = m; i > 0; i--) {
    long long zux = bb(x[i]), zuy = bb(y[i]);
    if (zux != zuy) {
      f[zux] = zuy;
      jk -= yh[zux] * yh[zuy];
      yh[zuy] += yh[zux];
    }
    ans[i - 2] = jk;
  }
  for (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 ll = long long;
using P = pair<int, int>;
const ll MOD = 1000000007;

class UnionFind {
public:
  vector<int> par;
  vector<int> rank;
  UnionFind(int n) { init(n); }
  void init(int n) {
    par.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
    rank.assign(n, 0);
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

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<ll> size(N, 1);
  UnionFind uf(N);

  vector<ll> ans(N);
  for (int i = M - 1; i >= 0; i--) {
    if (uf.same(A[i], B[i])) {
      ans[i] = 0;
    } else {
      ll a_size = size[uf.find(A[i])], b_size = size[uf.find(B[i])];
      ans[i] = a_size * b_size;
      uf.unite(A[i], B[i]);
      size[uf.find(A[i])] = a_size + b_size;
    }
  }
  ll cumsum = 0;
  for (int i = 0; i < M; i++) {
    cumsum += ans[i];
    cout << cumsum << endl;
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
const ll MOD = 1000000007;

class UnionFind {
public:
  vector<int> par;
  vector<int> rank;
  UnionFind(int n) { init(n); }
  void init(int n) {
    par.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
    rank.assign(n, 0);
  }
  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
};

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<ll> size(N, 1);
  UnionFind uf(N);

  vector<ll> ans(M);
  for (int i = M - 1; i >= 0; i--) {
    if (uf.same(A[i], B[i])) {
      ans[i] = 0;
    } else {
      ll a_size = size[uf.find(A[i])], b_size = size[uf.find(B[i])];
      ans[i] = a_size * b_size;
      uf.unite(A[i], B[i]);
      size[uf.find(A[i])] = a_size + b_size;
    }
  }
  ll cumsum = 0;
  for (int i = 0; i < M; i++) {
    cumsum += ans[i];
    cout << cumsum << endl;
  }

  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define REP(i, n) for (ll i = 0; i < (ll)n; i++)
#define INF 1000000000000000
using namespace std;
typedef long long ll;
typedef double db;
typedef string str;

struct UnionFind {
  vector<ll> par;
  vector<ll> rank;
  vector<ll> sz;

  UnionFind(ll n) { init(n); }

  void init(ll n) {
    par.resize(n), rank.resize(n), sz.resize(n);
    REP(i, n) {
      par[i] = i, rank[i] = 0;
      sz[i] = 1;
    }
  }

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

  void unite(ll x, ll y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(ll x, ll y) { return find(x) == find(y); }

  ll size(ll x) { return sz[find(x)]; }
};

int main() {
  ll n, m;
  cin >> n >> m;
  UnionFind uf(n);
  int a[m], b[m];
  REP(i, m) cin >> a[i] >> b[i];
  reverse(a, a + m);
  reverse(b, b + m);
  ll ans[m];
  ans[0] = n * (n - 1) / 2;
  REP(i, m - 1) {
    if (uf.same(a[i], b[i])) {
      ans[i + 1] = ans[i];
    } else {
      ans[i + 1] = ans[i] - uf.size(a[i]) * uf.size(b[i]);
      uf.unite(a[i], b[i]);
    }
  }
  reverse(ans, ans + m);
  REP(i, m) cout << ans[i] << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define REP(i, n) for (ll i = 0; i < (ll)n; i++)
#define INF 1000000000000000
using namespace std;
typedef long long ll;
typedef double db;
typedef string str;

struct UnionFind {
  vector<ll> par;
  vector<ll> rank;
  vector<ll> sz;

  UnionFind(ll n) { init(n); }

  void init(ll n) {
    par.resize(n), rank.resize(n), sz.resize(n);
    REP(i, n) {
      par[i] = i, rank[i] = 0;
      sz[i] = 1;
    }
  }

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

  void unite(ll x, ll y) {
    x = find(x), y = find(y);
    if (x == y)
      return;
    if (rank[x] < rank[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(ll x, ll y) { return find(x) == find(y); }

  ll size(ll x) { return sz[find(x)]; }
};

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

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

struct UnionFind {
  vll par;
  vll count;

  UnionFind(ll n) {
    par.resize(n), count.resize(n);
    rep(i, n) par[i] = i, count[i] = 1;
  }

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

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

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

  ll size(ll x) { return count[root(x)]; }
};

int main() {
  ll N, M;
  cin >> N >> M;
  vll A(M), B(M);
  rep(i, M) { cin >> A[i] >> B[i]; }

  UnionFind tree(N);
  vll ans(M);

  ll res = N * (N - 1) / 2;
  for (ll i = M - 1; i >= 0; i--) {
    ll a, b;
    a = A[i], b = B[i];
    ans[i] = res;
    if (tree.same(a, b) == false) {
      // この橋が異なるグループをつなぐようなら
      ll asize = tree.size(a), bsize = tree.size(b);
      res -= asize * bsize;
    }
    tree.unite(a, b);
  }

  rep(i, M) { cout << ans[i] << endl; }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < n; i++)
#define repr(i, n) for (ll i = n; i >= 0; i--)
#define inf LLONG_MAX
#define all(v) v.begin(), v.end()
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef vector<vll> vvll;

struct UnionFind {
  vll par;
  vll count;

  UnionFind(ll n) {
    par.resize(n), count.resize(n);
    rep(i, n) par[i] = i, count[i] = 1;
  }

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

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

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

  ll size(ll x) { return count[root(x)]; }
};

int main() {
  ll N, M;
  cin >> N >> M;
  vll A(M), B(M);
  rep(i, M) {
    cin >> A[i] >> B[i];
    A[i]--, B[i]--;
  }

  UnionFind tree(N);
  vll ans(M);

  ll res = N * (N - 1) / 2;
  for (ll i = M - 1; i >= 0; i--) {
    ll a, b;
    a = A[i], b = B[i];
    ans[i] = res;
    if (tree.same(a, b) == false) {
      // この橋が異なるグループをつなぐようなら
      ll asize = tree.size(a), bsize = tree.size(b);
      res -= asize * bsize;
    }
    tree.unite(a, b);
  }

  rep(i, M) { cout << ans[i] << endl; }

  return 0;
}
Problem p03108 (C++)

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

using namespace std;
using ll = long long;

struct node {
  int p;
  int v;
  int s;
};

int get_pid(vector<node> &vec, int i) {
  while (i != vec[i].p)
    i = vec[i].p;
  return i;
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<node> vec(n + 1);
  for (int i = 1; i <= n; ++i)
    vec[i] = {i, i, 1};

  vector<pair<int, int>> vec2(m);
  for (auto &v : vec2) {
    int a, b;
    cin >> a >> b;
    v = make_pair(a, b);
  }

  reverse(vec2.begin(), vec2.end());

  vector<int> ans;
  for (auto &v : vec2) {
    int a = v.first;
    int b = v.second;
    int ap = get_pid(vec, a);
    int bp = get_pid(vec, b);
    if (ap == bp) {
      ans.push_back(0);
    } else {
      int s = vec[ap].s + vec[bp].s;
      ans.push_back(vec[ap].s * vec[bp].s);
      vec[bp].p = ap;
      vec[ap].s = s;
    }
  }

  ll vsum = 0;
  for (auto itr = ans.rbegin(); itr != ans.rend(); ++itr) {
    vsum += *itr;
    cout << vsum << endl;
  }
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
using ll = long long;

struct node {
  int p;
  int v;
  int s;
};

int get_pid(vector<node> &vec, int i) {
  int p = i;
  while (p != vec[p].p)
    p = vec[p].p;
  int c = i;
  while (c != vec[c].p) {
    int n = vec[c].p;
    vec[c].p = p;
    c = n;
  }
  return p;
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<node> vec(n + 1);
  for (int i = 1; i <= n; ++i)
    vec[i] = {i, i, 1};

  vector<pair<int, int>> vec2(m);
  for (auto &v : vec2) {
    int a, b;
    cin >> a >> b;
    v = make_pair(a, b);
  }

  reverse(vec2.begin(), vec2.end());

  vector<int> ans;
  for (auto &v : vec2) {
    int a = v.first;
    int b = v.second;
    int ap = get_pid(vec, a);
    int bp = get_pid(vec, b);
    if (ap == bp) {
      ans.push_back(0);
    } else {
      int s = vec[ap].s + vec[bp].s;
      ans.push_back(vec[ap].s * vec[bp].s);
      vec[bp].p = ap;
      vec[ap].s = s;
    }
  }

  ll vsum = 0;
  for (auto itr = ans.rbegin(); itr != ans.rend(); ++itr) {
    vsum += *itr;
    cout << vsum << endl;
  }
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
int an = 0;
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
typedef pair<int, int> P;
const int xx[4] = {1, -1, 0, 0}, yy[4] = {0, 0, 1, -1};
struct tp {
  int x, y;
  ll cs;
};
const int wd = 1000001;

struct unf {
  vector<int> v, s;
  unf(int n) {
    v.resize(n);
    s.resize(n);
    for (int i = 0; i < n; i++)
      v[i] = i, s[i] = 1;
  }
  int root(int x) {
    if (v[x] == x)
      return x;
    return v[x] = root(v[x]);
  }
  void unite(int x, int y) {
    int p = root(x), q = root(y);
    if (p == q)
      return;
    v[p] = q, s[q] = s[p] + s[q];
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int sz(int k) { return s[root(k)]; }
  void print() {
    for (int x : v)
      cout << x << " ";
    cout << endl;
  }
  void print2() {
    for (int x : s)
      cout << x << " ";
    cout << endl;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  unf u(n);
  ll a[n], b[n], an[n];
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  for (int i = m - 1; i >= 0; i--) {
    if (u.same(a[i], b[i]))
      an[i] = 0;
    else {
      // cout<<u.sz(a[i])<<" "<<u.sz(b[i])<<endl;
      an[i] = u.sz(a[i]) * u.sz(b[i]);
      u.unite(a[i], b[i]);
    }
    // u.print();
    // cout<<"a"; u.print2();
  }
  for (int i = 1; i < m; i++) {
    an[i] += an[i - 1];
  }
  for (int i = 0; i < m; i++) {
    cout << an[i] << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
int an = 0;
const ll INF = 1e18;
const ll MOD = 1e9 + 7;
typedef pair<int, int> P;
const int xx[4] = {1, -1, 0, 0}, yy[4] = {0, 0, 1, -1};
struct tp {
  int x, y;
  ll cs;
};
const int wd = 1000001;

struct unf {
  vector<int> v, s;
  unf(int n) {
    v.resize(n);
    s.resize(n);
    for (int i = 0; i < n; i++)
      v[i] = i, s[i] = 1;
  }
  int root(int x) {
    if (v[x] == x)
      return x;
    return v[x] = root(v[x]);
  }
  void unite(int x, int y) {
    int p = root(x), q = root(y);
    if (p == q)
      return;
    v[p] = q, s[q] = s[p] + s[q];
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int sz(int k) { return s[root(k)]; }
  void print() {
    for (int x : v)
      cout << x << " ";
    cout << endl;
  }
  void print2() {
    for (int x : s)
      cout << x << " ";
    cout << endl;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  unf u(n);
  ll a[m], b[m], an[m];
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--, b[i]--;
  }
  for (int i = m - 1; i >= 0; i--) {
    if (u.same(a[i], b[i]))
      an[i] = 0;
    else {
      // cout<<u.sz(a[i])<<" "<<u.sz(b[i])<<endl;
      an[i] = u.sz(a[i]) * u.sz(b[i]);
      u.unite(a[i], b[i]);
    }
    // u.print();
    // cout<<"a"; u.print2();
  }
  for (int i = 1; i < m; i++) {
    an[i] += an[i - 1];
  }
  for (int i = 0; i < m; i++) {
    cout << an[i] << endl;
  }
}
Problem p03108 (C++)

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

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 + 1);
  vector<int> Tree(N, -1);
  vector<int> Treesize(N, 1);
  long long fuben = (long long)N * (N - 1) / 2;

  ans[M] = fuben;

  for (int i = M - 1; i > 0; i--) {
    int Ap = A[i], Bp = B[i];
    while (Tree[Ap] != -1)
      Ap = Tree[Ap];
    while (Tree[Bp] != -1)
      Bp = Tree[Bp];

    if (Ap != Bp) {
      fuben -= (long long)Treesize[Ap] * Treesize[Bp];
      Tree[Bp] = Ap;
      Treesize[Ap] += Treesize[Bp];
    }

    ans[i] = fuben;
  }

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

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

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 + 1);
  vector<int> Tree(N, -1);
  vector<int> Treesize(N, 1);
  long long fuben = (long long)N * (N - 1) / 2;

  ans[M] = fuben;

  for (int i = M - 1; i > 0; i--) {
    int Ap = A[i], Bp = B[i];
    while (Tree[Ap] != -1)
      Ap = Tree[Ap];
    while (Tree[Bp] != -1)
      Bp = Tree[Bp];

    if (Ap != Bp) {
      fuben -= (long long)Treesize[Ap] * Treesize[Bp];
      if (Treesize[Ap] < Treesize[Bp])
        swap(Ap, Bp);
      Tree[Bp] = Ap;
      Treesize[Ap] += Treesize[Bp];
    }

    ans[i] = fuben;
  }

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

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <vector>

using namespace std;

struct UnionFind {
  std::vector<std::size_t> par;
  std::vector<std::size_t> _size;

  UnionFind(std::size_t N) : par(N), _size(N, 1) {
    for (std::size_t i = 0; i < N; i++) {
      par[i] = i;
    }
  }

  std::size_t Root(std::size_t x) {
    if (par[x] == x) {
      return x;
    }
    return par[x] = Root(par[x]);
  }

  void Unite(std::size_t x, std::size_t y) {
    auto rx = Root(x);
    auto ry = Root(y);
    if (rx != ry) {
      if (_size[rx] < _size[ry]) {
        par[rx] = ry;
        _size[ry] += _size[rx];
      } else {
        par[ry] = rx;
        _size[rx] += _size[ry];
      }
    }
  }

  size_t Size(std::size_t x) { return _size[Root(x)]; }

  bool Same(std::size_t x, std::size_t y) {
    auto rx = Root(x);
    auto ry = Root(y);
    return rx == ry;
  }
};

int main() {
  int64_t n, m;
  cin >> n >> m;
  vector<int64_t> as(m), bs(m);
  for (int i = 0; i < m; i++) {
    cin >> as[i] >> bs[i];
  }
  vector<int64_t> ans_list;

  UnionFind uf(n);

  int64_t ans = n * (n - 1) / 2;
  ans_list.push_back(ans);
  for (int i = m - 1; i > 0; i--) {
    const int64_t sa = uf.Size(as[i]);
    const int64_t sb = uf.Size(bs[i]);
    if (!uf.Same(as[i], bs[i])) {
      ans -= uf.Size(as[i]) * uf.Size(bs[i]);
      uf.Unite(as[i], bs[i]);
    }
    ans_list.push_back(ans);
  }
  reverse(ans_list.begin(), ans_list.end());
  for (auto v : ans_list) {
    cout << v << endl;
  }
}

Fixed submission:
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <vector>

using namespace std;

struct UnionFind {
  std::vector<std::size_t> par;
  std::vector<std::size_t> _size;

  UnionFind(std::size_t N) : par(N), _size(N, 1) {
    for (std::size_t i = 0; i < N; i++) {
      par[i] = i;
    }
  }

  std::size_t Root(std::size_t x) {
    if (par[x] == x) {
      return x;
    }
    return par[x] = Root(par[x]);
  }

  void Unite(std::size_t x, std::size_t y) {
    auto rx = Root(x);
    auto ry = Root(y);
    if (rx != ry) {
      if (_size[rx] < _size[ry]) {
        par[rx] = ry;
        _size[ry] += _size[rx];
      } else {
        par[ry] = rx;
        _size[rx] += _size[ry];
      }
    }
  }

  size_t Size(std::size_t x) { return _size[Root(x)]; }

  bool Same(std::size_t x, std::size_t y) {
    auto rx = Root(x);
    auto ry = Root(y);
    return rx == ry;
  }
};

int main() {
  int64_t n, m;
  cin >> n >> m;
  vector<int64_t> as(m), bs(m);
  for (int i = 0; i < m; i++) {
    cin >> as[i] >> bs[i];
    as[i]--;
    bs[i]--;
  }
  vector<int64_t> ans_list;

  UnionFind uf(n);

  int64_t ans = n * (n - 1) / 2;
  ans_list.push_back(ans);
  for (int i = m - 1; i > 0; i--) {
    const int64_t sa = uf.Size(as[i]);
    const int64_t sb = uf.Size(bs[i]);
    if (!uf.Same(as[i], bs[i])) {
      ans -= uf.Size(as[i]) * uf.Size(bs[i]);
      uf.Unite(as[i], bs[i]);
    }
    ans_list.push_back(ans);
  }
  reverse(ans_list.begin(), ans_list.end());
  for (auto v : ans_list) {
    cout << v << endl;
  }
}
Problem p03108 (C++)

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

long long inf = LLONG_MAX;
vector<long long> id;

long long find(long long i) {
  if (id[i] <= 0)
    return i;
  return id[i] = find(id[i]);
}

long long unio(long long i, long long j) {
  long long u = find(i);
  long long k = find(j);
  if (find(i) == find(j))
    return 0;
  if (id[u] > id[k])
    swap(u, k);
  id[u] += id[k];
  id[k] = u;
  return id[u];
}

ll fact(ll n) {
  ll res = 1;
  for (ll i = 2; i <= n; i++)
    res = res * i;
  return res;
}

ll nCr(ll n, ll r) { return fact(n) / (fact(r) * fact(n - r)); }

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  ll n, m;
  cin >> n >> m;
  id.resize(n + 1, -1);
  vector<pair<ll, ll>> arr(m);
  for (int z = 0; z < m; z++) {
    ll a, b;
    cin >> a >> b;
    arr[z] = make_pair(a, b);
  }
  vector<ll> answer(m + 1);
  answer[m] = nCr(n, 2);
  for (int z = m - 1; z > 0; z--) {
    ll a = id[find(arr[z].first)];
    ll b = id[find(arr[z].second)];
    ll c = unio(arr[z].first, arr[z].second);
    if (c == 0) {
      answer[z] = answer[z + 1];
    } else {
      answer[z] = answer[z + 1] + nCr((-a), 2) + nCr((-b), 2) - nCr((-c), 2);
    }
  }
  for (int z = 1; z <= m; z++) {
    cout << answer[z] << endl;
  }
  cin >> n;
}

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

long long inf = LLONG_MAX;
vector<long long> id;

long long find(long long i) {
  if (id[i] <= 0)
    return i;
  return id[i] = find(id[i]);
}

long long unio(long long i, long long j) {
  long long u = find(i);
  long long k = find(j);
  if (find(i) == find(j))
    return 0;
  if (id[u] > id[k])
    swap(u, k);
  id[u] += id[k];
  id[k] = u;
  return id[u];
}

ll nCr(ll n, ll r) { return n * (n - 1) / 2; }

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  ll n, m;
  cin >> n >> m;
  id.resize(n + 1, -1);
  vector<pair<ll, ll>> arr(m);
  for (int z = 0; z < m; z++) {
    ll a, b;
    cin >> a >> b;
    arr[z] = make_pair(a, b);
  }
  vector<ll> answer(m + 1);
  answer[m] = nCr(n, 2);
  for (int z = m - 1; z > 0; z--) {
    ll a = id[find(arr[z].first)];
    ll b = id[find(arr[z].second)];
    ll c = unio(arr[z].first, arr[z].second);
    if (c == 0) {
      answer[z] = answer[z + 1];
    } else {
      answer[z] = answer[z + 1] + nCr((-a), 2) + nCr((-b), 2) - nCr((-c), 2);
    }
  }
  for (int z = 1; z <= m; z++) {
    cout << answer[z] << endl;
  }
  cin >> n;
}