Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#define ll long long
#define rep(i, n) for (ll i = 0; i < n; i++)
#define rep3(i, a, b) for (ll i = a; i >= b; i--)
#define vec vector<int>
#define vecll vector<ll>
using namespace std;
int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}
struct UnionFind {
  vec par, size;
  UnionFind(int n) : par(n), size(n) {
    rep(i, n) {
      par[i] = i;
      size[i] = 1;
    }
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return root(par[x]);
  }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    par[rx] = ry;
    size[ry] += size[rx];
  }
  bool same(int x, int y) { return root(x) == root(y); }
};
int main() {
  ll n = lin();
  int m = in();
  UnionFind tree(n);
  vecll a(m), b(m), ans(m);
  ans[m - 1] = 0;
  rep(i, m) {
    a[i] = in() - 1;
    b[i] = in() - 1;
  }
  rep3(i, m - 2, 0) {
    if (!tree.same(a[i + 1], b[i + 1])) {
      ans[i] = ans[i + 1] +
               tree.size[tree.root(a[i + 1])] * tree.size[tree.root(b[i + 1])];
      tree.unite(a[i + 1], b[i + 1]);
    } else
      ans[i] = ans[i + 1];
  }
  ll k = n * (n - 1) / 2;
  rep(i, m) cout << k - ans[i] << endl;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#define ll long long
#define rep(i, n) for (ll i = 0; i < n; i++)
#define rep3(i, a, b) for (ll i = a; i >= b; i--)
#define vec vector<int>
#define vecll vector<ll>
using namespace std;
int in() {
  int x;
  scanf("%d", &x);
  return x;
}
ll lin() {
  ll x;
  scanf("%lld", &x);
  return x;
}
struct UnionFind {
  vec par, size;
  UnionFind(int n) : par(n), size(n) {
    rep(i, n) {
      par[i] = i;
      size[i] = 1;
    }
  }
  int root(int x) {
    if (par[x] == x)
      return x;
    return root(par[x]);
  }
  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry)
      return;
    if (size[rx] < size[ry]) {
      par[rx] = ry;
      size[ry] += size[rx];
    } else {
      par[ry] = rx;
      size[rx] += size[ry];
    }
  }
  bool same(int x, int y) { return root(x) == root(y); }
};
int main() {
  ll n = lin();
  int m = in();
  UnionFind tree(n);
  vecll a(m), b(m), ans(m);
  ans[m - 1] = 0;
  rep(i, m) {
    a[i] = in() - 1;
    b[i] = in() - 1;
  }
  rep3(i, m - 2, 0) {
    if (!tree.same(a[i + 1], b[i + 1])) {
      ans[i] = ans[i + 1] +
               tree.size[tree.root(a[i + 1])] * tree.size[tree.root(b[i + 1])];
      tree.unite(a[i + 1], b[i + 1]);
    } else
      ans[i] = ans[i + 1];
  }
  ll k = n * (n - 1) / 2;
  rep(i, m) cout << k - ans[i] << endl;
}