Problem p03108 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define INF 100000000
#define ll long long int
using namespace std;

/*
vector <int> dx = {1,0,-1,0};
vector <int> dy = {0,1,0,-1};

*/

struct Node {
  ll parent;
  ll size;
};

vector<Node> UnionFind(100098);

int find(Node a);

void connect(Node a, Node b);

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

  for (int i = 1; i <= N; i++) {
    UnionFind[i].parent = -i;
    UnionFind[i].size = 1;
  }

  for (int i = M - 2; i >= 0; i--) {

    int a = A[i + 1];
    int b = B[i + 1];

    int roota = find(UnionFind[a]);
    int rootb = find(UnionFind[b]);

    ll delta = UnionFind[roota].size * UnionFind[rootb].size;

    bool flag = roota == rootb;

    connect(UnionFind[a], UnionFind[b]);

    if (not flag) {

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

      continue;

    } else {

      ans[i] = ans[i + 1]; //- UnionFind[-UnionFind[a].parent].size *
                           //UnionFind[-UnionFind[b].parent].size;

      continue;
    }
  }

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

  return 0;
}

int find(Node a) {
  if (a.parent < 0)
    return -a.parent;

  int par = find(UnionFind[a.parent]);

  UnionFind[par].size += a.size;
  a.size = 0;
  a.parent = par;

  return par;
}

void connect(Node a, Node b) {

  int apar = find(a);
  int bpar = find(b);

  if (apar == bpar)
    return;

  UnionFind[bpar].parent = apar;
  UnionFind[apar].size += UnionFind[bpar].size;
  UnionFind[bpar].size = 0;

  return;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define INF 100000000
#define ll long long int
using namespace std;

/*
vector <int> dx = {1,0,-1,0};
vector <int> dy = {0,1,0,-1};

*/

struct Node {
  ll parent;
  ll size;
};

vector<Node> UnionFind(100098);

int find(Node a);

void connect(Node a, Node b);

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

  for (int i = 1; i <= N; i++) {
    UnionFind[i].parent = -i;
    UnionFind[i].size = 1;
  }

  for (int i = M - 2; i >= 0; i--) {

    int a = A[i + 1];
    int b = B[i + 1];

    int roota = find(UnionFind[a]);
    int rootb = find(UnionFind[b]);

    ll delta = UnionFind[roota].size * UnionFind[rootb].size;

    bool flag = roota == rootb;

    connect(UnionFind[a], UnionFind[b]);

    if (not flag) {

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

      continue;

    } else {

      ans[i] = ans[i + 1]; //- UnionFind[-UnionFind[a].parent].size *
                           //UnionFind[-UnionFind[b].parent].size;

      continue;
    }
  }

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

  return 0;
}

int find(Node a) {
  if (a.parent < 0)
    return -a.parent;

  int par = find(UnionFind[a.parent]);

  UnionFind[par].size += a.size;
  a.size = 0;
  a.parent = par;

  return par;
}

void connect(Node a, Node b) {

  int apar = find(a);
  int bpar = find(b);

  if (apar == bpar)
    return;

  if (UnionFind[apar].size >= UnionFind[bpar].size) {

    UnionFind[bpar].parent = apar;
    UnionFind[apar].size += UnionFind[bpar].size;
    UnionFind[bpar].size = 0;

  } else {

    UnionFind[apar].parent = bpar;
    UnionFind[bpar].size += UnionFind[apar].size;
    UnionFind[apar].size = 0;
  }

  return;
}