Problem p02536 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
typedef int64_t ll;
typedef long double ld;
const ll MOD = 1000000007;
const ll MODA = 998244353;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
long long gcd(long long a, long long b) {
  ll gcdmax = max(a, b);
  ll gcdmin = min(a, b);
  while (true) {
    if (gcdmax % gcdmin == 0)
      break;
    else
      gcdmax %= gcdmin;
    swap(gcdmin, gcdmax);
  }
  return gcdmin;
}
ll powerup(ll N, ll P, ll M) {
  if (P == 0)
    return 1;
  else if (P % 2 == 0) {
    ll t = powerup(N, P / 2, M);
    return t * t % M;
  } else
    return N * powerup(N, P - 1, M) % M;
}
vector<ll> find_divisor(ll N) {
  ll k = 1;
  while (k * k <= N) {
    k++;
  }
  vector<ll> A(1);
  rep(i, k) {
    if (i == 1)
      A.at(0) = 1;
    else if (i >= 2) {
      if (N % i == 0)
        A.push_back(i);
    }
  }
  ll t = 0;
  t = A.size();
  rep(i, t) {
    if (A.at(t - i - 1) * A.at(t - i - 1) != N)
      A.push_back(N / A.at(t - 1 - i));
  }
  return A;
}
vector<ll> fac;
vector<ll> finv;
vector<ll> inv;
void COMinit(ll N, ll P) {
  rep(i, N + 1) {
    if (i == 0) {
      fac.push_back(1);
      finv.push_back(1);
      inv.push_back(1);
    } else if (i == 1) {
      fac.push_back(1);
      finv.push_back(1);
      inv.push_back(1);
    } else {
      fac.push_back(fac.at(i - 1) * i % P);
      inv.push_back(P - inv.at(P % i) * (P / i) % P);
      finv.push_back(finv.at(i - 1) * inv.at(i) % P);
    }
  }
}

ll COM(ll n, ll k, ll P) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac.at(n) * (finv.at(k) * finv.at(n - k) % P) % P;
}

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

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

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

  void unite(ll x, ll y) { // xとyの木を併合
    ll rx = root(x);       // xの根をrx
    ll ry = root(y);       // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(ll x, ll y) { // 2つのデータx, yが属する木が同じならtrueを返す
    ll rx = root(x);
    ll ry = root(y);
    return rx == ry;
  }

  ll COUNT(ll N) {
    vector<ll> count(N + 1);
    ll ans = 0;
    rep(i, N + 1) {
      if (count.at(root(i)) == 0) {
        ans++;
        count.at(root(i))++;
      }
    }
    return ans;
  }
};

int main() {
  ll N, M;
  cin >> N >> M;
  UnionFind tree(N);
  rep(i, M) {
    ll A, B;
    cin >> A >> B;
    tree.unite(A, B);
  }
  cout << tree.COUNT(N) - 2 << endl;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef int64_t ll;
typedef long double ld;
const ll MOD = 1000000007;
const ll MODA = 998244353;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
long long gcd(long long a, long long b) {
  ll gcdmax = max(a, b);
  ll gcdmin = min(a, b);
  while (true) {
    if (gcdmax % gcdmin == 0)
      break;
    else
      gcdmax %= gcdmin;
    swap(gcdmin, gcdmax);
  }
  return gcdmin;
}
ll powerup(ll N, ll P, ll M) {
  if (P == 0)
    return 1;
  else if (P % 2 == 0) {
    ll t = powerup(N, P / 2, M);
    return t * t % M;
  } else
    return N * powerup(N, P - 1, M) % M;
}
vector<ll> find_divisor(ll N) {
  ll k = 1;
  while (k * k <= N) {
    k++;
  }
  vector<ll> A(1);
  rep(i, k) {
    if (i == 1)
      A.at(0) = 1;
    else if (i >= 2) {
      if (N % i == 0)
        A.push_back(i);
    }
  }
  ll t = 0;
  t = A.size();
  rep(i, t) {
    if (A.at(t - i - 1) * A.at(t - i - 1) != N)
      A.push_back(N / A.at(t - 1 - i));
  }
  return A;
}
vector<ll> fac;
vector<ll> finv;
vector<ll> inv;
void COMinit(ll N, ll P) {
  rep(i, N + 1) {
    if (i == 0) {
      fac.push_back(1);
      finv.push_back(1);
      inv.push_back(1);
    } else if (i == 1) {
      fac.push_back(1);
      finv.push_back(1);
      inv.push_back(1);
    } else {
      fac.push_back(fac.at(i - 1) * i % P);
      inv.push_back(P - inv.at(P % i) * (P / i) % P);
      finv.push_back(finv.at(i - 1) * inv.at(i) % P);
    }
  }
}

ll COM(ll n, ll k, ll P) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac.at(n) * (finv.at(k) * finv.at(n - k) % P) % P;
}

struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

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

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

  void unite(ll x, ll y) { // xとyの木を併合
    ll rx = root(x);       // xの根をrx
    ll ry = root(y);       // yの根をry
    if (rx == ry)
      return; // xとyの根が同じ(=同じ木にある)時はそのまま
    par[rx] =
        ry; // xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
  }

  bool same(ll x, ll y) { // 2つのデータx, yが属する木が同じならtrueを返す
    ll rx = root(x);
    ll ry = root(y);
    return rx == ry;
  }

  ll COUNT(ll N) {
    vector<ll> count(N);
    ll ans = 0;
    rep(i, N) {
      if (count.at(root(i)) == 0) {
        ans++;
        count.at(root(i))++;
      }
    }
    return ans;
  }
};

int main() {
  ll N, M;
  cin >> N >> M;
  UnionFind tree(N);
  rep(i, M) {
    ll A, B;
    cin >> A >> B;
    tree.unite(A, B);
  }
  cout << tree.COUNT(N) - 1 << endl;
}