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

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

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() {
  int n, m;
  cin >> n >> m;
  vector<ll> ans;
  vector<int> a(m), b(m);
  rep(i, m) cin >> a[i] >> b[i];
  reverse(a.rbegin(), a.rend());
  reverse(b.rbegin(), b.rend());
  ll tmp = (ll)n * (ll)(n - 1) / 2;
  ans.push_back(tmp);
  UnionFind uf(n);
  rep(i, m) {
    if (!uf.same(a[i], b[i])) {
      int sa = uf.size(a[i]);
      int sb = uf.size(b[i]);
      tmp -= (ll)sa * (ll)sb;
      ans.push_back(tmp);
      uf.unite(a[i], b[i]);
    } else {
      ans.push_back(tmp);
    }
  }
  reverse(ans.begin(), ans.end());
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

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() {
  int n, m;
  cin >> n >> m;
  vector<ll> ans;
  vector<int> a(m), b(m);
  rep(i, m) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  reverse(a.rbegin(), a.rend());
  reverse(b.rbegin(), b.rend());
  ll tmp = (ll)n * (ll)(n - 1) / 2;
  ans.push_back(tmp);
  UnionFind uf(n);
  rep(i, m) {
    if (!uf.same(a[i], b[i])) {
      int sa = uf.size(a[i]);
      int sb = uf.size(b[i]);
      tmp -= (ll)sa * (ll)sb;
      ans.push_back(tmp);
      uf.unite(a[i], b[i]);
    } else {
      ans.push_back(tmp);
    }
  }
  reverse(ans.begin(), ans.end());
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << endl;
  }
}
Problem p03108 (C++)

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

using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

const long long INF = 1LL << 60;
long long dp[100100];

class UnionFind {
public:
  vector<int> Parent;

  UnionFind(int N) { Parent = vector<int>(N, -1); }

  int root(int X) {
    if (Parent[X] < 0)
      return X;
    return Parent[X] = root(Parent[X]);
  }

  int size(int X) { return -Parent[root(X)]; }

  bool unite(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--) {
    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.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 <bits/stdc++.h>

using namespace std;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

const long long INF = 1LL << 60;
long long dp[100100];

class UnionFind {
public:
  vector<int> Parent;

  UnionFind(int N) { Parent = vector<int>(N, -1); }

  int root(int X) {
    if (Parent[X] < 0)
      return X;
    return Parent[X] = root(Parent[X]);
  }

  int size(int X) { return -Parent[root(X)]; }

  bool unite(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--) {
    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.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 <iostream>
#include <utility>
#include <vector>
using namespace std;
struct unionfind {
  vector<int> p, sz;
  unionfind(int n) {
    p = vector<int>(n, -1);
    sz = vector<int>(n, 1);
  }
  int root(int x) {
    if (p[x] == -1) {
      return x;
    } else {
      p[x] = root(p[x]);
      return p[x];
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
  pair<int, int> unite(int x, int y) {
    x = root(x);
    y = root(y);
    pair<int, int> ans = make_pair(sz[x], sz[y]);
    p[y] = x;
    sz[x] += sz[y];
    return ans;
  }
};
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 G(N);
  for (int i = M - 2; i >= 0; i--) {
    if (!G.same(A[i + 1], B[i + 1])) {
      pair<int, int> sz = G.unite(A[i + 1], B[i + 1]);
      ans[i] = ans[i + 1] - (long long)sz.first * sz.second;
    } else {
      ans[i] = ans[i + 1];
    }
  }
  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
}

Fixed submission:
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
struct unionfind {
  vector<int> p, sz;
  unionfind(int n) {
    p = vector<int>(n, -1);
    sz = vector<int>(n, 1);
  }
  int root(int x) {
    if (p[x] == -1) {
      return x;
    } else {
      p[x] = root(p[x]);
      return p[x];
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
  pair<int, int> unite(int x, int y) {
    x = root(x);
    y = root(y);
    pair<int, int> ans = make_pair(sz[x], sz[y]);
    p[y] = x;
    sz[x] += sz[y];
    return ans;
  }
};
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 G(N);
  for (int i = M - 2; i >= 0; i--) {
    if (!G.same(A[i + 1], B[i + 1])) {
      pair<int, int> sz = G.unite(A[i + 1], B[i + 1]);
      ans[i] = ans[i + 1] - (long long)sz.first * sz.second;
    } else {
      ans[i] = ans[i + 1];
    }
  }
  for (int i = 0; i < M; i++) {
    cout << ans[i] << endl;
  }
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct UnionFind {
  vector<ll> par;
  vector<ll> rank;
  vector<ll> sz;
  UnionFind(ll n) : par(n), rank(n), sz(n) {
    for (ll i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
      sz[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) {
    x = root(x);
    y = root(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 root(x) == root(y); }
  ll size(ll x) {
    x = root(x);
    return sz[x];
  }
};

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


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct UnionFind {
  vector<ll> par;
  vector<ll> rank;
  vector<ll> sz;
  UnionFind(ll n) : par(n), rank(n), sz(n) {
    for (ll i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
      sz[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) {
    x = root(x);
    y = root(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 root(x) == root(y); }
  ll size(ll x) {
    x = root(x);
    return sz[x];
  }
};

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

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

struct UnionFind {
  vector<int> par;
  vector<long> sizes;
  UnionFind(int N) : par(N), sizes(N) {
    for (int i = 0; i < N; ++i) {
      par[i] = i;
      sizes[i] = 1;
    }
  }
  int root(int x) { return par[x] == x ? x : root(par[x]); }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      par[rx] = ry;
      sizes[ry] += sizes[rx];
    }
  }
  long size(int x) { return sizes[root(x)]; }
  bool same(int x, int y) { return root(x) == root(y); }
};

int main() {
  int a[100010], b[100010], m, x, y;
  long n, c[100010];
  cin >> n >> m;
  for (int i = 0; i < m; ++i)
    cin >> a[i] >> b[i];
  UnionFind tree(n);
  c[m] = n * (n - 1) / 2;
  for (int i = m - 1; i >= 0; --i) {
    x = a[i] - 1;
    y = b[i] - 1;
    if (tree.same(x, y)) {
      c[i] = c[i + 1];
    } else {
      c[i] = c[i + 1] - tree.size(x) * tree.size(y);
      tree.unite(x, y);
    }
  }
  for (int i = 1; i <= m; ++i) {
    cout << c[i] - c[0] << endl;
  }
}

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

struct UnionFind {
  vector<int> par;
  vector<long> sizes;
  UnionFind(int N) : par(N), sizes(N) {
    for (int i = 0; i < N; ++i) {
      par[i] = i;
      sizes[i] = 1;
    }
  }
  int root(int x) { return par[x] == x ? x : root(par[x]); }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      int sx = sizes[rx];
      int sy = sizes[ry];
      if (sx < sy) {
        par[rx] = ry;
        sizes[ry] += sx;
      } else {
        par[ry] = rx;
        sizes[rx] += sy;
      }
    }
  }
  long size(int x) { return sizes[root(x)]; }
  bool same(int x, int y) { return root(x) == root(y); }
};

int main() {
  int a[100010], b[100010], m, x, y;
  long n, c[100010];
  cin >> n >> m;
  for (int i = 0; i < m; ++i)
    cin >> a[i] >> b[i];
  UnionFind tree(n);
  c[m] = n * (n - 1) / 2;
  for (int i = m - 1; i >= 0; --i) {
    x = a[i] - 1;
    y = b[i] - 1;
    if (tree.same(x, y)) {
      c[i] = c[i + 1];
    } else {
      c[i] = c[i + 1] - tree.size(x) * tree.size(y);
      tree.unite(x, y);
    }
  }
  for (int i = 1; i <= m; ++i) {
    cout << c[i] - c[0] << endl;
  }
}
Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iterator>
#include <map>
#include <vector>

using namespace std;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vll = vector<ll>;
using vvll = vector<vll>;

struct v_t {
  int p;
  vi c;
};

using vvt = vector<v_t>;

void vmove(vvt &v, int a, int b) {
  for (int mbc : v[b].c) {
    v[mbc].p = a;
  }
  copy(v[b].c.begin(), v[b].c.end(), back_inserter(v[a].c));
  v[b].c.clear();
}

ll uni(vvt &v, ll ans, int n, int a, int b) {
  if (v[a].p == v[b].p)
    return ans;

  ll an = v[v[a].p].c.size();
  ll bn = v[v[b].p].c.size();

  if (v[a].c.size() < v[b].c.size())
    swap(a, b);
  vmove(v, v[a].p, v[b].p);
  return ans - an * (n - an) - bn * (n - bn) + (an + bn) * (n - (an + bn));
}

int main(void) {
  int n, m;

  while (scanf("%d%d", &n, &m) == 2) {
    vi a(m), b(m);
    vector<v_t> v(n + 1);
    vll ans(m + 1);

    for (int i = 1; i <= n; i++) {
      v[i].p = i;
      v[i].c.push_back(i);
    }

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

    ans[m] = (ll)n * (n - 1);
    for (int i = m - 1; i >= 0; i--) {
      ans[i] = ans[i + 1];
      ans[i] = uni(v, ans[i + 1], n, a[i], b[i]);
    }
    for (int i = 1; i <= m; i++) {
      printf("%lld\n", ans[i] / 2);
    }
  }

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <functional>
#include <iterator>
#include <map>
#include <vector>

using namespace std;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
using vll = vector<ll>;
using vvll = vector<vll>;

struct v_t {
  int p;
  vi c;
};

using vvt = vector<v_t>;

void vmove(vvt &v, int a, int b) {
  for (int mbc : v[b].c) {
    v[mbc].p = a;
  }
  copy(v[b].c.begin(), v[b].c.end(), back_inserter(v[a].c));
  v[b].c.clear();
}

ll uni(vvt &v, ll ans, int n, int a, int b) {
  if (v[a].p == v[b].p)
    return ans;

  ll an = v[v[a].p].c.size();
  ll bn = v[v[b].p].c.size();

  if (v[v[a].p].c.size() < v[v[b].p].c.size())
    swap(a, b);
  vmove(v, v[a].p, v[b].p);
  return ans - an * (n - an) - bn * (n - bn) + (an + bn) * (n - (an + bn));
}

int main(void) {
  int n, m;

  while (scanf("%d%d", &n, &m) == 2) {
    vi a(m), b(m);
    vector<v_t> v(n + 1);
    vll ans(m + 1);

    for (int i = 1; i <= n; i++) {
      v[i].p = i;
      v[i].c.push_back(i);
    }

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

    ans[m] = (ll)n * (n - 1);
    for (int i = m - 1; i >= 0; i--) {
      ans[i] = ans[i + 1];
      ans[i] = uni(v, ans[i + 1], n, a[i], b[i]);
    }
    for (int i = 1; i <= m; i++) {
      printf("%lld\n", ans[i] / 2);
    }
  }

  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); }
  int root(int a) {
    if (parent[a] < 0)
      return a;
    return parent[a] = root(parent[a]);
  }
  int size(int a) { return -parent[root(a)]; }
  int 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;
  int a[m], b[m];
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
  }
  UnionFind uf(n);
  long long ans[m];
  ans[m - 1] = (long long)n * (n - 1) / 2;
  for (int i = m - 1; i >= 1; i--) {
    ans[i - 1] = ans[i];
    if (uf.root(a[i]) != uf.root(b[i])) {
      ans[i - 1] = ans[i] - (long long)uf.size(a[i]) * uf.size(b[i]);
      uf.connect(a[i], b[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); }
  int root(int a) {
    if (parent[a] < 0)
      return a;
    return parent[a] = root(parent[a]);
  }
  int size(int a) { return -parent[root(a)]; }
  int 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;
  int a[m], b[m];
  for (int i = 0; i < m; i++) {
    cin >> a[i] >> b[i];
    a[i]--;
    b[i]--;
  }
  UnionFind uf(n);
  long long ans[m];
  ans[m - 1] = (long long)n * (n - 1) / 2;
  for (int i = m - 1; i >= 1; i--) {
    ans[i - 1] = ans[i];
    if (uf.root(a[i]) != uf.root(b[i])) {
      ans[i - 1] = ans[i] - (long long)uf.size(a[i]) * uf.size(b[i]);
      uf.connect(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):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, m, n) for (int i = m; i < n; ++i)
#define rem(i, m, n) for (int i = m; i >= n; --i)
typedef long long ll;
#define mod 1000000007
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

class UnionFind {
public:
  vector<int> uni;
  UnionFind(int s) : uni(s, -1) {}

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

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

  bool isConnect(int a, int b) { return root(a) == root(b); }

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N), B(N);
  rep(i, 0, M) {
    cin >> A[i] >> B[i];
    A[i]--, B[i]--;
  }
  vector<ll> ans(M);
  UnionFind uf(N);
  rem(i, M - 1, 0) {
    if (uf.isConnect(A[i], B[i]))
      continue;
    ans[i] = (ll)uf.size(A[i]) * (ll)uf.size(B[i]);
    uf.connect(A[i], B[i]);
  }
  rep(i, 1, M) ans[i] += ans[i - 1];
  rep(i, 0, M) cout << ans[i] << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, m, n) for (int i = m; i < n; ++i)
#define rem(i, m, n) for (int i = m; i >= n; --i)
typedef long long ll;
#define mod 1000000007
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

class UnionFind {
public:
  vector<int> uni;
  UnionFind(int s) : uni(s, -1) {}

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

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

  bool isConnect(int a, int b) { return root(a) == root(b); }

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(M), B(M);
  rep(i, 0, M) {
    cin >> A[i] >> B[i];
    A[i]--, B[i]--;
  }
  vector<ll> ans(M);
  UnionFind uf(N);
  rem(i, M - 1, 0) {
    if (uf.isConnect(A[i], B[i]))
      continue;
    ans[i] = (ll)uf.size(A[i]) * (ll)uf.size(B[i]);
    uf.connect(A[i], B[i]);
  }
  rep(i, 1, M) ans[i] += ans[i - 1];
  rep(i, 0, M) cout << ans[i] << endl;
  return 0;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;

#define MOD 1000000007

struct UnionFind {
  vector<int> data;
  void init(int n) { data.assign(n, -1); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  bool same(int x, int y) { return root(x) == root(y); }
  bool unite(int x, int y) {
    x = root(x), y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  int size(int x) { return -data[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;
  uf.init(n);
  ll res = 1ll * n * (n - 1) / 2;
  vector<ll> ans(m);
  for (int i = m - 1; i >= 0; --i) {
    ans[i] = res;
    if (!uf.same(a[i], b[i])) {
      res -= 1ll * uf.size(a[i]) * uf.size(b[i]);
      uf.unite(a[i], b[i]);
    }
  }
  for (int i = 0; i < m; ++i) {
    cout << ans[i] << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;

#define MOD 1000000007

struct UnionFind {
  vector<int> data;
  void init(int n) { data.assign(n, -1); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  bool same(int x, int y) { return root(x) == root(y); }
  bool unite(int x, int y) {
    x = root(x), y = root(y);
    if (x != y) {
      if (data[y] < data[x])
        swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  int size(int x) { return -data[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];
    a[i]--, b[i]--;
  }
  UnionFind uf;
  uf.init(n);
  ll res = 1ll * n * (n - 1) / 2;
  vector<ll> ans(m);
  for (int i = m - 1; i >= 0; --i) {
    ans[i] = res;
    if (!uf.same(a[i], b[i])) {
      res -= 1ll * uf.size(a[i]) * uf.size(b[i]);
      uf.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):
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MOD 1000000007
#define REP(i, N) for (int i = 0; i < N; ++i)
#define REP1(i, N) for (int i = 1; i <= N; ++i)
#define RREP(i, N) for (int i = N - 1; i >= 0; --i)
#define ALL(a) a.begin(), a.end()

struct UnionFind {
  vector<int> par;
  vector<int> sz;
  UnionFind(int n) { init(n); }

  void init(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      sz[i] = 1;
    }
  }

  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 (sz[x] < sz[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
    }
  }

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

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

int main() {
  int n, m;
  cin >> n >> m;
  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<ll> ans;
  ll res = 1ll * n * (n - 1) / 2;
  for (int i = m - 1; i >= 0; --i) {
    ans.push_back(res);
    if (!uf.same(a[i], b[i])) {
      res -= 1ll * uf.size(a[i]) * uf.size(b[i]);
      uf.unite(a[i], b[i]);
    }
  }
  reverse(ans.begin(), ans.end());
  for (int i = 0; i < m; ++i) {
    cout << ans[i] << endl;
  }
  return 0;
}

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

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define MOD 1000000007
#define REP(i, N) for (int i = 0; i < N; ++i)
#define REP1(i, N) for (int i = 1; i <= N; ++i)
#define RREP(i, N) for (int i = N - 1; i >= 0; --i)
#define ALL(a) a.begin(), a.end()

struct UnionFind {
  vector<int> par;
  vector<int> sz;
  UnionFind(int n) { init(n); }

  void init(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      sz[i] = 1;
    }
  }

  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 (sz[x] < sz[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      sz[x] += sz[y];
    }
  }

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

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

int main() {
  int n, m;
  cin >> n >> m;
  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<ll> ans;
  ll res = 1ll * n * (n - 1) / 2;
  for (int i = m - 1; i >= 0; --i) {
    ans.push_back(res);
    if (!uf.same(a[i], b[i])) {
      res -= 1ll * uf.size(a[i]) * uf.size(b[i]);
      uf.unite(a[i], b[i]);
    }
  }
  reverse(ans.begin(), ans.end());
  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;
typedef long long ll;
const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;

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

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

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

int main() {

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

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

  reverse(a.begin(), a.end());
  reverse(b.begin(), b.end());

  vector<ll> ans;

  ll t = (ll)n * ((ll)n - 1) / 2;
  ans.push_back(t);

  UnionFind tree(n);

  for (int i = 0; i < m - 1; ++i) {
    ll a_size = (ll)tree.size(a[i]);
    ll b_size = (ll)tree.size(b[i]);

    tree.unite(a[i], b[i]);

    ll size = (ll)tree.size(a[i]);

    if (t > 0 && size > a_size && size > b_size) {
      t -= size * (size - 1) / 2 - (a_size) * (a_size - 1) / 2 -
           (b_size) * (b_size - 1) / 2;
    }

    if (t < 0)
      t = 0;

    ans.push_back(t);
  }

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

  for (ll i = 0; i < ans.size(); ++i) {
    cout << ans[i] << endl;
  }
}

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

using namespace std;
typedef long long ll;
const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;

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

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

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

int main() {

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

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

  reverse(a.begin(), a.end());
  reverse(b.begin(), b.end());

  vector<ll> ans;

  ll t = (ll)n * ((ll)n - 1) / 2;
  ans.push_back(t);

  UnionFind tree(n);

  for (int i = 0; i < m - 1; ++i) {
    ll a_size = (ll)tree.size(a[i]);
    ll b_size = (ll)tree.size(b[i]);

    tree.unite(a[i], b[i]);

    ll size = (ll)tree.size(a[i]);

    if (t > 0 && size > a_size && size > b_size) {
      t -= size * (size - 1) / 2 - (a_size) * (a_size - 1) / 2 -
           (b_size) * (b_size - 1) / 2;
    }

    if (t < 0)
      t = 0;

    ans.push_back(t);
  }

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

  for (ll i = 0; i < ans.size(); ++i) {
    cout << ans[i] << endl;
  }
}
Problem p03108 (C++)

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

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      siz[i] = 1;
    }
  }

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

  int size(int x) {
    if (par[x] == x)
      return siz[x];
    else
      return siz[x] = size(par[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      par[ry] = rx;
      siz[rx] += siz[ry];
    }
  }

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

signed main() {
  // cout << fixed << setprecision(10) << flush;

  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<int> ans(m);
  for (int i = m - 1; i >= 0; i--) {
    int sa = uf.size(a[i]);
    int sb = uf.size(b[i]);
    if (uf.same(a[i], b[i])) {
      ans[i] = 0;
    } else {
      ans[i] = sa * sb;
    }
    uf.unite(a[i], b[i]);
  }

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

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

  return 0;
}

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

struct UnionFind {
  vector<int> par;
  vector<int> siz;

  UnionFind(int n) : par(n), siz(n) {
    for (int i = 0; i < n; i++) {
      par[i] = i;
      siz[i] = 1;
    }
  }

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

  int size(int x) {
    if (par[x] == x)
      return siz[x];
    else
      return siz[x] = size(par[x]);
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      par[ry] = rx;
      siz[rx] += siz[ry];
    }
  }

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

signed main() {
  // cout << fixed << setprecision(10) << flush;

  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<int> ans(m);
  for (int i = m - 1; i >= 0; i--) {
    int sa = uf.size(a[i]);
    int sb = uf.size(b[i]);
    if (uf.same(a[i], b[i])) {
      ans[i] = 0;
    } else {
      ans[i] = sa * sb;
    }
    uf.unite(a[i], b[i]);
  }

  for (int i = 0; i < m - 1; i++) {
    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 <bits/stdc++.h>
using namespace std;
using ll = long long;

struct union_find {
  vector<int> par;

  union_find(int n) : par(n, -1) {}

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

  bool unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return false;
    if (par[rx] > par[ry])
      swap(rx, ry);
    par[rx] += par[ry];
    par[ry] = rx;
    return true;
  }

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

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

int main() {
  ll n, m;
  cin >> n >> m;
  union_find tree(n);
  vector<pair<ll, ll>> bridge(m);
  for (int i = 0; i < m; i++) {
    cin >> bridge[i].first >> bridge[i].second;
  }
  vector<ll> ans(m, 0);
  ans[0] = n * (n - 1) / 2;
  reverse(bridge.begin(), bridge.end());
  for (int i = 0; i < m; i++) {
    ans[i + 1] = ans[i];
    ll x = bridge[i].first - 1;
    ll y = bridge[i].second - 1;
    ll xs = tree.size(x);
    ll ys = tree.size(y);
    if (tree.same(x, y) == false) {
      ans[i + 1] -= xs * ys;
    }
    tree.unite(x, y);
  }

  reverse(ans.begin(), ans.end());
  for (int i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }
}

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

struct union_find {
  vector<int> par;

  union_find(int n) : par(n, -1) {}

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

  bool unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return false;
    if (par[rx] > par[ry])
      swap(rx, ry);
    par[rx] += par[ry];
    par[ry] = rx;
    return true;
  }

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

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

int main() {
  ll n, m;
  cin >> n >> m;
  union_find tree(n);
  vector<pair<ll, ll>> bridge(m);
  for (int i = 0; i < m; i++) {
    cin >> bridge[i].first >> bridge[i].second;
  }
  vector<ll> ans(m, 0);
  ans[0] = n * (n - 1) / 2;
  reverse(bridge.begin(), bridge.end());
  for (int i = 0; i < m - 1; i++) {
    ans[i + 1] = ans[i];
    ll x = bridge[i].first - 1;
    ll y = bridge[i].second - 1;
    ll xs = tree.size(x);
    ll ys = tree.size(y);
    if (tree.same(x, y) == false) {
      ans[i + 1] -= xs * ys;
    }
    tree.unite(x, y);
  }

  reverse(ans.begin(), ans.end());
  for (int i = 0; i < m; i++) {
    cout << ans[i] << endl;
  }
}
Problem p03108 (C++)

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

using namespace std;

class UnionFind {
public:
  vector<int> par;

  UnionFind(int N) { par = vector<int>(N, -1); }

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

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

  int connect(int x, int y) {
    x = root(x);
    y = root(y);

    if (x == y)
      return false;

    if (size(x) < size(y))
      swap(x, y);

    par[x] += par[y];
    par[y] = x;

    return true;
  }
};

int main() {
  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 uni(N);
  vector<long long> ans(M, 0);
  ans[M - 1] = (long long)N * (N - 1) / 2;
  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;
}


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

using namespace std;

class UnionFind {
public:
  vector<int> par;

  UnionFind(int N) { par = vector<int>(N, -1); }

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

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

  int connect(int x, int y) {
    x = root(x);
    y = root(y);

    if (x == y)
      return false;

    if (size(x) < size(y))
      swap(x, y);

    par[x] += par[y];
    par[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]--;
  }

  UnionFind uni(N);
  vector<long long> ans(M, 0);
  ans[M - 1] = (long long)N * (N - 1) / 2;
  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;
}
Problem p03108 (C++)

Buggy submission (status: Runtime Error):
#include <assert.h>
#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;
  UnionFind(int size) { data.resize(size, -1); }
  int find(int now) {
    return (data[now] < 0 ? now : data[now] = find(data[now]));
  }
  int size(int now) { return -data[find(now)]; }
  bool same(int x, int y) { return (find(x) == find(y)); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    data[x] += data[y];
    data[y] = x;
    return;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<pair<int, int>> edge(M);
  for (int i = 0; i < M; i++) {
    cin >> edge[i].first >> edge[i].second;
    edge[i].first--;
    edge[i].second--;
  }
  vector<long long> ans(M);
  UnionFind uf(N);
  for (int i = M; -1 < i; i--)
    if (i == M)
      ans[i - 1] = (long long)N * (N - 1) / 2;
    else {
      if (uf.same(edge[i].first, edge[i].second))
        ans[i - 1] = ans[i];
      else {
        ans[i - 1] = ans[i] - (long long)uf.size(edge[i].first) *
                                  uf.size(edge[i].second);
        uf.unite(edge[i].first, edge[i].second);
      }
    }
  for (long long t : ans)
    cout << t << endl;

  return 0;
}


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

using namespace std;

struct UnionFind {
  vector<int> data;
  UnionFind(int size) { data.resize(size, -1); }
  int find(int now) {
    return (data[now] < 0 ? now : data[now] = find(data[now]));
  }
  int size(int now) { return -data[find(now)]; }
  bool same(int x, int y) { return (find(x) == find(y)); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    data[x] += data[y];
    data[y] = x;
    return;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<pair<int, int>> edge(M);
  for (int i = 0; i < M; i++) {
    cin >> edge[i].first >> edge[i].second;
    edge[i].first--;
    edge[i].second--;
  }
  vector<long long> ans(M);
  UnionFind uf(N);
  for (int i = M; 0 < i; i--)
    if (i == M)
      ans[i - 1] = (long long)N * (N - 1) / 2;
    else {
      if (uf.same(edge[i].first, edge[i].second))
        ans[i - 1] = ans[i];
      else {
        ans[i - 1] = ans[i] - (long long)uf.size(edge[i].first) *
                                  uf.size(edge[i].second);
        uf.unite(edge[i].first, edge[i].second);
      }
    }
  for (long long t : ans)
    cout << t << endl;

  return 0;
}
Problem p03108 (C++)

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

vector<ll> parent(100010, -1);
ll N, M, x, y;

ll find(ll x) { return parent[x] < 0 ? x : parent[x] = find(parent[x]); }
void unite(ll x, ll y) {
  if (find(x) != find(y)) {
    if (parent[x] > parent[y])
      swap(x, y);
    parent[x] += parent[y];
    parent[y] = x;
  }
}
ll size(ll x) { return -parent[find(x)]; }

int main() {
  cin >> N >> M;
  ll A[100010];
  ll B[100010];
  vector<ll> ans;

  REP(i, M) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  ll t = (N * (N - 1)) / 2;
  REP(i, M) {
    ans.push_back(t);
    ll x = A[M - i - 1], y = B[M - i - 1];
    if (find(x) != find(y)) {
      t -= size(x) * size(y);
      unite(x, y);
    }
  }
  reverse(ans.begin(), ans.end());
  for (auto &it : ans) {
    cout << it << endl;
  }
  return 0;
}


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

vector<ll> parent(100010, -1);
ll N, M, x, y;

ll find(ll x) { return parent[x] < 0 ? x : parent[x] = find(parent[x]); }
void unite(ll x, ll y) {
  x = find(x), y = find(y);
  if (x != y) {
    if (parent[x] > parent[y])
      swap(x, y);
    parent[x] += parent[y];
    parent[y] = x;
  }
}
ll size(ll x) { return -parent[find(x)]; }

int main() {
  cin >> N >> M;
  ll A[100010];
  ll B[100010];
  vector<ll> ans;

  REP(i, M) {
    cin >> A[i] >> B[i];
    A[i]--;
    B[i]--;
  }

  ll t = (N * (N - 1)) / 2;
  REP(i, M) {
    ans.push_back(t);
    ll x = A[M - i - 1], y = B[M - i - 1];
    if (find(x) != find(y)) {
      t -= size(x) * size(y);
      unite(x, y);
    }
  }
  reverse(ans.begin(), ans.end());
  for (auto &it : ans) {
    cout << it << endl;
  }
  return 0;
}
Problem p03108 (C++)

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

class UnionFind {
public:
  vector<long long> par;
  vector<long long> size;

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

  long long root(long long x) {
    while (par[x] != x) {
      x = par[x];
    }
    return x;
  }

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

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

  long long siz(long long x) { return size[root(x)]; }
};

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

  vector<vector<long long>> stock(M, vector<long long>(2, 0));
  vector<long long> ans(M, 0);

  for (long long i = 0; i < M; i++) {
    long long a, b;
    cin >> a >> b;
    stock[i][0] = a - 1;
    stock[i][1] = b - 1;
  }

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

  for (long long i = M - 1; i > 0; i--) {
    long long a = stock[i][0];
    long long b = stock[i][1];
    if (uf.same(a, b)) {
      ans[i - 1] = ans[i];
    } else {
      ans[i - 1] = ans[i] - uf.siz(a) * uf.siz(b);
      uf.unite(a, b);
    }
  }

  for (auto a : ans) {
    cout << a << endl;
  }

  return 0;
}

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

class UnionFind {
public:
  vector<long long> par;
  vector<long long> size;

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

  long long root(long long x) {
    while (par[x] != x) {
      x = par[x];
    }
    return x;
  }

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

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

  long long siz(long long x) { return size[root(x)]; }
};

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

  vector<vector<long long>> stock(M, vector<long long>(2, 0));
  vector<long long> ans(M, 0);

  for (long long i = 0; i < M; i++) {
    long long a, b;
    cin >> a >> b;
    stock[i][0] = a - 1;
    stock[i][1] = b - 1;
  }

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

  for (long long i = M - 1; i > 0; i--) {
    long long a = stock[i][0];
    long long b = stock[i][1];
    if (uf.same(a, b)) {
      ans[i - 1] = ans[i];
    } else {
      ans[i - 1] = ans[i] - uf.siz(a) * uf.siz(b);
      uf.unite(a, b);
    }
  }

  for (auto a : ans) {
    cout << a << endl;
  }

  return 0;
}
Problem p03108 (C++)

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

using namespace std;
#define ll long long
#define REP(i, n) for (auto i = 0; i < n; i++)
#define REPR(i, n) for (auto i = n - 1; i >= 0; i--)

typedef pair<ll, ll> LP;

const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> data;
  // dataの各要素について
  // 負の値:その集合のルートであること示す。また、その絶対値は集合の要素数となっている。
  // 正の値:親ノードの番号(dataのインデックス)。root()を呼び出すたびに集合のルートを指すように書きなおされるので木はそんなに深くならない

  // 初期化 size:最大要素数
  UnionFind(int size) : data(size, -1) {}

  // 集合を併合する
  // すでに同じ集合だった場合は、falseが返る
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      // 要素数の大きな方へ合併するためのswap
      if (data[y] < data[x])
        swap(x, y);
      // 要素数を加算する
      data[x] += data[y];
      // yの属する集合のルートをxに変更
      data[y] = x;
    }
    return x != y;
  }

  // 同じ集合かどうか判定
  bool same(int x, int y) { return root(x) == root(y); }

  // 集合の識別番号を返す
  // 負の値を持つものがその集合のルート
  // 正の値は同じ集合に属するものを指す(辿ればいずれルートへ着く)
  int root(int x) { return (data[x] < 0) ? x : data[x] = root(data[x]); }
  // 集合の要素数を返す
  int size(int x) { return -data[root(x)]; }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<LP> AB(m);
  REP(i, m) { cin >> AB[i].first >> AB[i].second; }
  UnionFind tree(n);
  ll ans[m];
  ll sum = n * (n - 1) / 2;
  REPR(i, m) {
    ans[i] = sum;
    if (!tree.same(AB[i].first, AB[i].second)) {
      sum -= tree.size(AB[i].first) * tree.size(AB[i].second);
      tree.unite(AB[i].first, AB[i].second);
    }
  }
  REP(i, m) { cout << ans[i] << endl; }
}

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

using namespace std;
#define ll long long
#define REP(i, n) for (auto i = 0; i < n; i++)
#define REPR(i, n) for (auto i = n - 1; i >= 0; i--)

typedef pair<ll, ll> LP;

const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> data;
  // dataの各要素について
  // 負の値:その集合のルートであること示す。また、その絶対値は集合の要素数となっている。
  // 正の値:親ノードの番号(dataのインデックス)。root()を呼び出すたびに集合のルートを指すように書きなおされるので木はそんなに深くならない

  // 初期化 size:最大要素数
  UnionFind(int size) : data(size, -1) {}

  // 集合を併合する
  // すでに同じ集合だった場合は、falseが返る
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      // 要素数の大きな方へ合併するためのswap
      if (data[y] < data[x])
        swap(x, y);
      // 要素数を加算する
      data[x] += data[y];
      // yの属する集合のルートをxに変更
      data[y] = x;
    }
    return x != y;
  }

  // 同じ集合かどうか判定
  bool same(int x, int y) { return root(x) == root(y); }

  // 集合の識別番号を返す
  // 負の値を持つものがその集合のルート
  // 正の値は同じ集合に属するものを指す(辿ればいずれルートへ着く)
  int root(int x) { return (data[x] < 0) ? x : data[x] = root(data[x]); }
  // 集合の要素数を返す
  int size(int x) { return -data[root(x)]; }
};

int main() {
  ll n, m;
  cin >> n >> m;
  vector<LP> AB(m);
  REP(i, m) { cin >> AB[i].first >> AB[i].second; }
  UnionFind tree(n);
  ll ans[m];
  ll sum = n * (n - 1) / 2;
  REPR(i, m) {
    ans[i] = sum;
    if (!tree.same(AB[i].first - 1, AB[i].second - 1)) {
      sum -= tree.size(AB[i].first - 1) * tree.size(AB[i].second - 1);
      tree.unite(AB[i].first - 1, AB[i].second - 1);
    }
  }
  REP(i, m) { cout << ans[i] << endl; }
}