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

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
#define mp std::make_pair
#define ll long long int
#define abs(n) ((n > 0) ? (n) : ((n) * (-1)))
#define CEIL(a, b) (((a) + ((b)-1)) / (b))
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
#define VREP(v)                                                                \
  for (std::vector<ll>::iterator itr = (v).begin(); itr != (v).end(); itr++)
#define VALL(v) ((v).begin(), (v).end())
#define errln(v) cerr << (v) << endl;
#define println(v) cout << (v) << endl;

int p[10001];
int par[10001];

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

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

void unite(int x, int y) {
  x = root(x);
  y = root(y);
  if (x == y)
    return;
  par[x] = y;
}

int main(int argc, const char *argv[]) {
  int N, M;
  cin >> N >> M;

  FOR(i, 1, N) {
    cin >> p[i];
    par[i] = i;
  }

  FOR(i, 1, M) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }
  int ret = 0;
  FOR(i, 1, N) {
    if (same(i, p[i]))
      ret++;
  }
  println(ret);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
#define mp std::make_pair
#define ll long long int
#define abs(n) ((n > 0) ? (n) : ((n) * (-1)))
#define CEIL(a, b) (((a) + ((b)-1)) / (b))
#define FOR(i, a, b) for (int i = (a); i <= (b); ++i)
#define REP(i, n) FOR(i, 0, (n)-1)
#define VREP(v)                                                                \
  for (std::vector<ll>::iterator itr = (v).begin(); itr != (v).end(); itr++)
#define VALL(v) ((v).begin(), (v).end())
#define errln(v) cerr << (v) << endl;
#define println(v) cout << (v) << endl;

int p[100001];
int par[100001];

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

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

void unite(int x, int y) {
  x = root(x);
  y = root(y);
  if (x == y)
    return;
  par[x] = y;
}

int main(int argc, const char *argv[]) {
  int N, M;
  cin >> N >> M;

  FOR(i, 1, N) {
    cin >> p[i];
    par[i] = i;
  }

  FOR(i, 1, M) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }
  int ret = 0;
  FOR(i, 1, N) {
    if (same(i, p[i]))
      ret++;
  }
  println(ret);

  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, a) range(i, 0, a)
using namespace std;

class unionFindTree {
private:
  vector<int> tree;
  vector<int> rank;
  vector<int> elem;

public:
  unionFindTree() {}

  unionFindTree(int sz) {
    tree = vector<int>(sz);
    rank = vector<int>(sz, 0);
    elem = vector<int>(sz, 0);
    for (int i = 0; i < tree.size(); i++)
      tree[i] = i;
  }

  unionFindTree(const unionFindTree &o) {
    tree = o.tree;
    rank = o.rank;
    elem = o.elem;
  }

  unionFindTree &operator=(const unionFindTree &o) {
    tree = o.tree;
    rank = o.rank;
    elem = o.elem;
    return (*this);
  };

  int root(int x) { return tree[x] == x ? x : tree[x] = root(tree[x]); }

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

  void unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return;

    if (rank[a] < rank[b])
      swap(a, b);

    tree[b] = a;
    rank[a] += rank[a] == rank[b];
    elem[a] += elem[b];
  }

  int size() { return tree.size(); }

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

int n, m;
vector<int> p, x, y;

int main() {
  cin >> n >> m;
  p = vector<int>(n);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  x = y = vector<int>(m);
  unionFindTree tree(100);
  rep(i, m) {
    cin >> x[i] >> y[i];
    tree.unite(x[i] - 1, y[i] - 1);
  }

  int cnt = 0;
  rep(i, n) cnt += tree.root(i) == tree.root(p[i]);
  cout << cnt << endl;

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, a) range(i, 0, a)
using namespace std;

class unionFindTree {
private:
  vector<int> tree;
  vector<int> rank;
  vector<int> elem;

public:
  unionFindTree() {}

  unionFindTree(int sz) {
    tree = vector<int>(sz);
    rank = vector<int>(sz, 0);
    elem = vector<int>(sz, 0);
    for (int i = 0; i < tree.size(); i++)
      tree[i] = i;
  }

  unionFindTree(const unionFindTree &o) {
    tree = o.tree;
    rank = o.rank;
    elem = o.elem;
  }

  unionFindTree &operator=(const unionFindTree &o) {
    tree = o.tree;
    rank = o.rank;
    elem = o.elem;
    return (*this);
  };

  int root(int x) { return tree[x] == x ? x : tree[x] = root(tree[x]); }

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

  void unite(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return;

    if (rank[a] < rank[b])
      swap(a, b);

    tree[b] = a;
    rank[a] += rank[a] == rank[b];
    elem[a] += elem[b];
  }

  int size() { return tree.size(); }

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

int n, m;
vector<int> p, x, y;

int main() {
  cin >> n >> m;
  p = vector<int>(n);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  x = y = vector<int>(m);
  unionFindTree tree(n);
  rep(i, m) {
    cin >> x[i] >> y[i];
    tree.unite(x[i] - 1, y[i] - 1);
  }

  int cnt = 0;
  rep(i, n) cnt += tree.root(i) == tree.root(p[i]);
  cout << cnt << endl;

  return 0;
}
Problem p03354 (C++)

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

typedef long long ll;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n) {
    for (int i = 0; i < n; ++i) {
      par.at(i) = i;
    }
  }

  int root(int x) {
    if (par.at(x) == x) {
      return x;
    } else {
      return root(par.at(x));
    }
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) {
      return;
    } else {
      par.at(rx) = ry;
    }
  }

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

int main() {
  int n, m, i;
  cin >> n >> m;

  vector<int> p(n);

  for (i = 0; i < n; ++i) {
    cin >> p.at(i);
  }

  UnionFind tree(n);

  for (i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }

  int ans = 0;
  for (i = 0; i < n; ++i) {
    if (tree.same(i, p.at(i) - 1)) {
      ++ans;
    }
  }
  cout << ans << endl;
  return 0;
}

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

typedef long long ll;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n) {
    for (int i = 0; i < n; ++i) {
      par.at(i) = i;
    }
  }

  int root(int x) {
    if (par.at(x) == x) {
      return x;
    } else {
      return par.at(x) = root(par.at(x));
    }
  }

  void unite(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx == ry) {
      return;
    } else {
      par.at(rx) = ry;
    }
  }

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

int main() {
  int n, m, i;
  cin >> n >> m;

  vector<int> p(n);

  for (i = 0; i < n; ++i) {
    cin >> p.at(i);
  }

  UnionFind tree(n);

  for (i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }

  int ans = 0;
  for (i = 0; i < n; ++i) {
    if (tree.same(i, p.at(i) - 1)) {
      ++ans;
    }
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

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

struct UnionFind {
  vi p, r;
  UnionFind(int n) {
    p.resize(n, -1);
    r.resize(n, 1);
  }
  int find(int x) {
    if (p[x] == -1)
      return x;
    else
      return p[x] = find(p[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] > r[y]) {
      swap(x, y);
    }
    if (r[x] == r[y]) {
      r[y]++;
    }
    p[x] = y;
  }
};

int main() {
  int n, m, x, y, cnt = 0;
  cin >> n >> m;

  UnionFind uf(n);
  vi p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    uf.unite(x, y);
  }
  for (int i = 1; i <= n; i++) {
    if (uf.find(p[i]) == uf.find(i)) {
      cnt++;
    }
  }
  cout << cnt << endl;
  return 0;
}

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

struct UnionFind {
  vi p, r;
  UnionFind(int n) {
    p.resize(n, -1);
    r.resize(n, 1);
  }
  int find(int x) {
    if (p[x] == -1)
      return x;
    else
      return p[x] = find(p[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;
    if (r[x] > r[y]) {
      swap(x, y);
    }
    if (r[x] == r[y]) {
      r[y]++;
    }
    p[x] = y;
  }
};

int main() {
  int n, m, x, y, cnt = 0;
  cin >> n >> m;

  UnionFind uf(n + 1);
  vi p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    uf.unite(x, y);
  }
  for (int i = 1; i <= n; i++) {
    if (uf.find(p[i]) == uf.find(i)) {
      cnt++;
    }
  }
  cout << cnt << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
int N, M, parent[10010], urank[10010], pn[10010];
int x, y, one, two;
int ufind(int a) {
  if (parent[a] == a)
    return a;
  return ufind(parent[a]);
}
void uSet(int a, int b) {
  int x, y;
  x = ufind(a);
  y = ufind(b);
  if (x == y)
    return;
  if (urank[x] > urank[y])
    parent[y] = x;
  else if (urank[x] == urank[y]) {
    parent[y] = x;
    urank[x]++;
  } else
    parent[x] = y;
}
int main() {
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= N; i++)
    scanf("%d", &pn[i]);
  for (int i = 0; i <= N; i++) {
    parent[i] = i;
    urank[i] = 1;
  }
  for (int i = 0; i < M; i++) {
    scanf("%d %d", &one, &two);
    uSet(one, two);
  }
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    if (ufind(pn[i]) == ufind(i))
      ans++;
  }
  printf("%d", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
int N, M, parent[100010], urank[100010], pn[100010];
int x, y, one, two;
int ufind(int a) {
  if (parent[a] == a)
    return a;
  return ufind(parent[a]);
}
void uSet(int a, int b) {
  int x, y;
  x = ufind(a);
  y = ufind(b);
  if (x == y)
    return;
  if (urank[x] > urank[y])
    parent[y] = x;
  else if (urank[x] == urank[y]) {
    parent[y] = x;
    urank[x]++;
  } else
    parent[x] = y;
}
int main() {
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= N; i++)
    scanf("%d", &pn[i]);
  for (int i = 0; i <= N; i++) {
    parent[i] = i;
    urank[i] = 1;
  }
  for (int i = 0; i < M; i++) {
    scanf("%d %d", &one, &two);
    uSet(one, two);
  }
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    if (ufind(pn[i]) == ufind(i))
      ans++;
  }
  printf("%d", ans);
  return 0;
}
Problem p03354 (C++)

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

using namespace std;
int par[100010], ran[100010];

void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    ran[i] = i;
  }
}

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

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

int main() {
  int n, m, a[100010], b[100010], i, cnt = 0;
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    cin >> a[i];
    b[a[i]] = i;
  }
  init(2 * n);
  for (i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }
  for (i = 1; i <= n; i++) {
    if (a[i] == i) {
      cnt++;
    } else {
      if (same(i, b[i])) {
        cnt++;
      }
    }
  }
  cout << cnt << endl;
}

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

using namespace std;
int par[200010], ran[200010];

void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    ran[i] = i;
  }
}

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

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

int main() {
  int n, m, a[100010], b[100010], i, cnt = 0;
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    cin >> a[i];
    b[a[i]] = i;
  }
  init(2 * n);
  for (i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    unite(x, y);
  }
  for (i = 1; i <= n; i++) {
    if (a[i] == i) {
      cnt++;
    } else {
      if (same(i, b[i])) {
        cnt++;
      }
    }
  }
  cout << cnt << endl;
}
Problem p03354 (C++)

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

int par[100001], h[100001], p[100000];
void init_tree() {
  for (int i = 0; i < 100001; i++) {
    par[i] = i;
    h[i] = 0;
  }
}
int find(int a) {
  if (par[a] == a) {
    return a;
  } else {
    return par[a] = find(par[a]);
  }
}
void unite(int a, int b) {
  if (h[a] > h[b]) {
    par[b] = a;
  } else {
    par[a] = b;
    if (h[a] == h[b]) {
      h[b]++;
    }
  }
}
bool issame(int a, int b) { return find(a) == find(b); }
int main() {
  init_tree();
  int N, M, x, y;
  scanf("%d %d", &N, &M);
  for (int i = 0; i < N; i++) {
    scanf("%d", p + i);
  }
  for (int i = 0; i < M; i++) {
    scanf("%d %d", &x, &y);
    unite(x, y);
  }
  int c = 0;
  for (int i = 0; i < N; i++) {
    if (issame(i + 1, p[i])) {
      c++;
    }
  }
  printf("%d\n", c);
  return 0;
}


Fixed submission:
#include <cstdio>
using namespace std;

int par[100001], h[100001], p[100000];
void init_tree() {
  for (int i = 0; i < 100001; i++) {
    par[i] = i;
    h[i] = 0;
  }
}
int find(int a) {
  if (par[a] == a) {
    return a;
  } else {
    return par[a] = find(par[a]);
  }
}
void unite(int a, int b) {
  a = find(a);
  b = find(b);
  if (h[a] > h[b]) {
    par[b] = a;
  } else {
    par[a] = b;
    if (h[a] == h[b]) {
      h[b]++;
    }
  }
}
bool issame(int a, int b) { return find(a) == find(b); }
int main() {
  init_tree();
  int N, M, x, y;
  scanf("%d %d", &N, &M);
  for (int i = 0; i < N; i++) {
    scanf("%d", p + i);
  }
  for (int i = 0; i < M; i++) {
    scanf("%d %d", &x, &y);
    unite(x, y);
  }
  int c = 0;
  for (int i = 0; i < N; i++) {
    if (issame(i + 1, p[i])) {
      c++;
    }
  }
  printf("%d\n", c);
  return 0;
}
Problem p03354 (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 long long ll;

const ll INF = 1e15;

struct UnionFind {
  vector<ll> par;
  vector<ll> rnk;

  UnionFind(ll n) {
    par.assign(n, 0);
    rnk.assign(n, 1);
    for (ll i = 0; i < n; i++) {
      par[i] = i;
    }
  }

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

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

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

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<ll> p(N);
  rep(i, N) cin >> p[i];
  UnionFind uf(M + 50);
  rep(i, M) {
    ll x, y;
    cin >> x >> y;
    uf.unite(x, y);
    // cout << "c" << endl;
  }

  int res = 0;
  rep(i, N) {
    if (p[i] == i + 1)
      res++;
    else if (uf.same(p[i], i + 1))
      res++;
  }

  cout << res << endl;
  return 0;
}

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

const ll INF = 1e15;

struct UnionFind {
  vector<ll> par;
  vector<ll> rnk;

  UnionFind(ll n) {
    par.assign(n, 0);
    rnk.assign(n, 1);
    for (ll i = 0; i < n; i++) {
      par[i] = i;
    }
  }

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

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

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

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

int main() {
  int N, M;
  cin >> N >> M;
  vector<ll> p(N);
  rep(i, N) cin >> p[i];
  UnionFind uf(10000010);
  rep(i, M) {
    ll x, y;
    cin >> x >> y;
    uf.unite(x, y);
    // cout << "c" << endl;
  }

  int res = 0;
  rep(i, N) {
    if (p[i] == i + 1)
      res++;
    else if (uf.same(p[i], i + 1))
      res++;
  }

  cout << res << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

int n, m, u, v;
int a[100050], fa[100050], pos[100050];

int find(int x) {
  if (fa[x] == x)
    return x;
  else
    return fa[x] = find(fa[x]);
}

int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    fa[i] = i;
    pos[a[i]] = i;
  }
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    fa[u] = v;
  }
  int res = 0;
  for (int i = 1; i <= n; i++) {
    if (find(i) == find(pos[i]))
      res++;
  }
  printf("%d\n", res);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

int n, m, u, v;
int a[100050], fa[100050], pos[100050];

int find(int x) {
  if (fa[x] == x)
    return x;
  else
    return fa[x] = find(fa[x]);
}

int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    fa[i] = i;
    pos[a[i]] = i;
  }
  for (int i = 1; i <= m; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    fa[find(u)] = find(v);
  }
  int res = 0;
  for (int i = 1; i <= n; i++) {
    if (find(i) == find(pos[i]))
      res++;
  }
  printf("%d\n", res);
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 10e+6
#define DEKA 1000000007

using namespace std;

// union-find

int par[100005];    // parents
int hukasa[100005]; // depth

// search root
int find(int x) {
  if (par[x] < 0)
    return x;
  else
    return par[x] = find(par[x]);
}
// xとyの集合を併合

int setsize(int n) { return -par[n]; }

void unit(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;

  if (hukasa[x] < hukasa[y]) {
    par[y] += par[x];
    par[x] = y;
  } else {
    par[x] += par[y];
    par[y] = x;
    if (hukasa[x] == hukasa[y])
      hukasa[x]++;
  }
}

// xとyは同じ集合に入るか？

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

int main() {
  int n, m;
  cin >> n >> m;

  for (int i = 1; i <= n; i++) {
    par[i] = -1;
    hukasa[i] = 1;
  }

  int p[n + 10];
  for (int i = 1; i <= n; i++)
    cin >> p[i];
  vector<pair<int, int>> pairs(n + 10);
  for (int i = 1; i <= m; i++) {
    cin >> pairs[i].first >> pairs[i].second;
    unit(p[pairs[i].first], p[pairs[i].second]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    if (same(i, p[i]) == 1)
      ans++;
  cout << ans << endl;
}


Fixed submission:
#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 10e+6
#define DEKA 1000000007

using namespace std;

// union-find

int par[100005];    // parents
int hukasa[100005]; // depth

// search root
int find(int x) {
  if (par[x] < 0)
    return x;
  else
    return par[x] = find(par[x]);
}
// xとyの集合を併合

int setsize(int n) { return -par[n]; }

void unit(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y)
    return;

  if (hukasa[x] < hukasa[y]) {
    par[y] += par[x];
    par[x] = y;
  } else {
    par[x] += par[y];
    par[y] = x;
    if (hukasa[x] == hukasa[y])
      hukasa[x]++;
  }
}

// xとyは同じ集合に入るか？

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

int main() {
  int n, m;
  cin >> n >> m;

  for (int i = 1; i <= n; i++) {
    par[i] = -1;
    hukasa[i] = 1;
  }

  int p[n + 10];
  for (int i = 1; i <= n; i++)
    cin >> p[i];
  vector<pair<int, int>> pairs(m + 10);
  for (int i = 1; i <= m; i++) {
    cin >> pairs[i].first >> pairs[i].second;
    unit(p[pairs[i].first], p[pairs[i].second]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    if (same(i, p[i]) == 1)
      ans++;
  cout << ans << endl;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
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)]; }

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

  vector<int> p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }

  UnionFind uni(n);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    uni.connect(x, y);
  }

  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (uni.root(i) == uni.root(p[i]))
      ans++;
  }

  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
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)]; }

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

  vector<int> p(n + 1);
  for (int i = 1; i <= n; i++) {
    cin >> p[i];
  }

  UnionFind uni(n + 1);
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    uni.connect(x, y);
  }

  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (uni.root(i) == uni.root(p[i]))
      ans++;
  }

  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }

  // 再帰的に辿ることで親を調べる
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }

  // 親が同じならば同じ集合に属する
  bool same(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;
    // 新しい要素を加えた時に、rootに対して辺を張る(merge technique)
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  // 新しいノードを集合に加えた時に、-1をrootに加算するため、
  // rootには、集合に属するノードの数に負符号を付加したものが保存されている。
  int size(int x) { return -par[root(x)]; }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> v(n);
  rep(i, n) cin >> v[i];

  UnionFind uf(n);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    uf.merge(x, y);
  }

  int ans = 0;
  rep(i, n) {
    if (uf.same(i + 1, v[i]))
      ans++;
  }

  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }

  // 再帰的に辿ることで親を調べる
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }

  // 親が同じならば同じ集合に属する
  bool same(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;
    // 新しい要素を加えた時に、rootに対して辺を張る(merge technique)
    if (par[x] > par[y])
      swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  // 新しいノードを集合に加えた時に、-1をrootに加算するため、
  // rootには、集合に属するノードの数に負符号を付加したものが保存されている。
  int size(int x) { return -par[root(x)]; }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> v(n);
  rep(i, n) cin >> v[i];

  UnionFind uf(n + 1);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    uf.merge(x, y);
  }

  int ans = 0;
  rep(i, n) {
    if (uf.same(i + 1, v[i]))
      ans++;
  }

  cout << ans << endl;
}
Problem p03354 (C++)

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

using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

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

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

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

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

  long int p[N];
  for (long int i = 0; i < N; i++) {
    cin >> p[i];
  }

  long int x, y;
  for (long int i = 0; i < M; i++) {
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }

  long int cnt = 0;
  for (long int i = 0; i < N; i++) {
    if (tree.same(i, p[i])) {
      cnt++;
    }
  }

  cout << cnt << endl;

  return 0;
}

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

using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

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

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

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

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

  long int p[N];
  for (long int i = 0; i < N; i++) {
    cin >> p[i];
  }

  long int x, y;
  for (long int i = 0; i < M; i++) {
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }

  long int cnt = 0;
  for (long int i = 0; i < N; i++) {
    if (tree.same(i, p[i] - 1)) {
      cnt++;
    }
  }

  cout << cnt << endl;

  return 0;
}
Problem p03354 (C++)

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

#define rep(i, n) for (int i = 0; i < n; i++)

const int MAXN = 1e5;

int par[MAXN];
int rnk[MAXN];
void init(int n) {
  for (int i = 0; i < n; ++i) {
    par[i] = i;
    rnk[i] = 0;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
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;
  if (rnk[x] < rnk[y])
    par[x] = y;
  else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      ++rnk[x];
  }
}

int N, M;
vector<int> p, x, y;
// 数列Pが与えられる。
// x_i, y_iをswapできる。
// 移動可能なindexでグループを作る。
// 5-1, 4-2, 3
// これらのindexがいくつ含まれるかがスコア
// 1-3, 5-4, 2
// => 2

void input_int_array(int n, vector<int> &vec) {
  for (int i = 0, tmp = 0; i < n && cin >> tmp; i++)
    vec[i] = tmp;
}

void input() {
  cin >> N >> M;
  cin.ignore();
  p = vector<int>(N);
  x = vector<int>(M);
  y = vector<int>(M);
  // 3という数字が2番目にあるならば、2番目と3番目が交換可能出あってほしい。
  rep(i, N) {
    int index;
    cin >> index;
    p[index] = i + 1;
  }
  cin.ignore();
  rep(i, M) {
    cin >> x[i] >> y[i];
    cin.ignore();
  }
}

int solve() {
  int score = 0;
  // これを忘れると、永遠に解けない.
  init(N);
  rep(i, M) unite(x[i], y[i]);
  rep(i, N) {
    int index = i + 1;
    // piが、i番目と交換できれば良い。
    if (same(index, p[index])) {
      score += 1;
    }
  }
  return score;
}

int main() {
  input();
  cout << solve() << endl;
}

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

#define rep(i, n) for (int i = 0; i < n; i++)

const int MAXN = 1e5;

int par[MAXN];
int rnk[MAXN];
void init(int n) {
  for (int i = 0; i < n; ++i) {
    par[i] = i;
    rnk[i] = 0;
  }
}
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
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;
  if (rnk[x] < rnk[y])
    par[x] = y;
  else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      ++rnk[x];
  }
}

int N, M;
vector<int> p, x, y;
// 数列Pが与えられる。
// x_i, y_iをswapできる。
// 移動可能なindexでグループを作る。
// 5-1, 4-2, 3
// これらのindexがいくつ含まれるかがスコア
// 1-3, 5-4, 2
// => 2

void input_int_array(int n, vector<int> &vec) {
  for (int i = 0, tmp = 0; i < n && cin >> tmp; i++)
    vec[i] = tmp;
}

void input() {
  cin >> N >> M;
  cin.ignore();
  p = vector<int>(N + 1);
  x = vector<int>(M + 1);
  y = vector<int>(M + 1);
  // 3という数字が2番目にあるならば、2番目と3番目が交換可能出あってほしい。
  rep(i, N) {
    int index;
    cin >> index;
    p[index] = i + 1;
  }
  cin.ignore();
  rep(i, M) {
    cin >> x[i] >> y[i];
    cin.ignore();
  }
}

int solve() {
  int score = 0;
  // これを忘れると、永遠に解けない.
  init(N);
  rep(i, M) unite(x[i], y[i]);
  rep(i, N) {
    int index = i + 1;
    // piが、i番目と交換できれば良い。
    if (same(index, p[index])) {
      score += 1;
    }
  }
  return score;
}

int main() {
  input();
  cout << solve() << endl;
}
Problem p03354 (C++)

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

#define rep(i, x, n) for (int i = x; i < n; i++)
typedef long long ll;

const int INF = 1e9 + 7;

using namespace std;

class UnionFind {
public:
  vector<int> tree;

  UnionFind(int n) : tree(n) { rep(i, 0, n) tree[i] = i; }

  int root(int x) { // データxの根を取得
    if (tree[x] == x)
      return x;
    else
      return root(tree[x]);
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);
    int ry = root(y);

    if (rx == ry)
      return;
    else
      tree[rx] = ry;
  }

  bool same(int x, int y) { // データxとデータyの根が同じか判定
    return (root(x) == root(y));
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

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

  vector<int> p(n);
  rep(i, 0, n) cin >> p[i];

  UnionFind uni(n);

  rep(i, 0, m) {
    int x, y;
    cin >> x >> y;

    uni.unite(x - 1, y - 1);
  }

  int res = 0;
  rep(i, 0, n) {
    if (uni.same(p[i] - 1, i))
      res++;
  }

  cout << res << endl;
  return 0;
}


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

#define rep(i, x, n) for (int i = x; i < n; i++)
typedef long long ll;

const int INF = 1e9 + 7;

using namespace std;

class UnionFind {
public:
  vector<int> tree;

  UnionFind(int n) : tree(n) { rep(i, 0, n) tree[i] = i; }

  int root(int x) { // データxの根を取得
    if (tree[x] == x)
      return x;
    else
      return tree[x] = root(tree[x]); // 根に直接つなぎ直す
  }

  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);
    int ry = root(y);

    if (rx == ry)
      return;
    else
      tree[rx] = ry;
  }

  bool same(int x, int y) { // データxとデータyの根が同じか判定
    return (root(x) == root(y));
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

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

  vector<int> p(n);
  rep(i, 0, n) cin >> p[i];

  UnionFind uni(n);

  rep(i, 0, m) {
    int x, y;
    cin >> x >> y;

    uni.unite(x - 1, y - 1);
  }

  int res = 0;
  rep(i, 0, n) {
    if (uni.same(p[i] - 1, i))
      res++;
  }

  cout << res << endl;
  return 0;
}
Problem p03354 (C++)

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

using namespace std;

int a[10010];
vector<int> vec[10010];
int pre[10010];
// 在find的同时进行路径压缩
int Find(int x) {
  int p, tmp;
  p = x;
  while (x != pre[x])
    x = pre[x];
  while (p != x) {
    tmp = pre[p];
    pre[p] = x;
    p = tmp;
  }
  return x;
}

void join(int x, int y) {
  int fx = Find(x);
  int fy = Find(y);
  if (fx != fy)
    pre[fx] = fy;
}
priority_queue<int> Q1;
priority_queue<int> Q2;
int main() {
  int n, m, x, y;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    pre[i] = i;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &x, &y);
    join(x, y);
  }
  for (int i = 1; i <= n; i++) {
    int f = Find(i);
    vec[f].push_back(i);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < vec[i].size(); j++) {
      Q1.push(vec[i][j]);
      Q2.push(a[vec[i][j]]);
    }
    while (1) {
      if (Q1.empty() || Q2.empty())
        break;
      int t1 = Q1.top();
      int t2 = Q2.top();
      if (t1 == t2) {
        ans++;
        Q1.pop();
        Q2.pop();
      } else if (t1 < t2) {
        Q2.pop();
      } else
        Q1.pop();
    }
    while (!Q1.empty())
      Q1.pop();
    while (!Q2.empty())
      Q2.pop();
  }
  cout << ans << endl;
  return 0;
}


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

using namespace std;

int a[100010];
vector<int> vec[100010];
int pre[100010];
// 在find的同时进行路径压缩
int Find(int x) {
  int p, tmp;
  p = x;
  while (x != pre[x])
    x = pre[x];
  while (p != x) {
    tmp = pre[p];
    pre[p] = x;
    p = tmp;
  }
  return x;
}

void join(int x, int y) {
  int fx = Find(x);
  int fy = Find(y);
  if (fx != fy)
    pre[fx] = fy;
}
priority_queue<int> Q1;
priority_queue<int> Q2;
int main() {
  int n, m, x, y;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    pre[i] = i;
  for (int i = 1; i <= n; i++)
    scanf("%d", &a[i]);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &x, &y);
    join(x, y);
  }
  for (int i = 1; i <= n; i++) {
    int f = Find(i);
    vec[f].push_back(i);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < vec[i].size(); j++) {
      Q1.push(vec[i][j]);
      Q2.push(a[vec[i][j]]);
    }
    while (1) {
      if (Q1.empty() || Q2.empty())
        break;
      int t1 = Q1.top();
      int t2 = Q2.top();
      if (t1 == t2) {
        ans++;
        Q1.pop();
        Q2.pop();
      } else if (t1 < t2) {
        Q2.pop();
      } else
        Q1.pop();
    }
    while (!Q1.empty())
      Q1.pop();
    while (!Q2.empty())
      Q2.pop();
  }
  cout << ans << endl;
  return 0;
}
Problem p03354 (C++)

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

typedef long long ll;
#define fi first
#define se second
#define SORT(a) sort(a.begin(), a.end())
#define REP(i, n) for (int i = 0; i < (n); i++)
#define MP(a, b) make_pair(a, b)

using namespace std;

int par[23456];
int rnk[23456];

void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 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 (rnk[x] < rnk[y])
    par[x] = y;
  else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      rnk[x]++;
  }
}

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

int main() {

  int n, m;
  cin >> n >> m;
  int p[n + 1];
  init(n + 1);
  for (int i = 1; i < n + 1; i++)
    cin >> p[i];
  REP(i, m) {
    int x, y;
    cin >> x >> y;
    unite(p[x], p[y]);
  }

  int ans = 0;
  for (int i = 1; i < n + 1; i++) {
    if (same(i, p[i]))
      ans++;
  }

  cout << ans;
  return 0;
}


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

typedef long long ll;
#define fi first
#define se second
#define SORT(a) sort(a.begin(), a.end())
#define REP(i, n) for (int i = 0; i < (n); i++)
#define MP(a, b) make_pair(a, b)

using namespace std;

int par[234567];
int rnk[234567];

void init(int n) {
  for (int i = 0; i < n; i++) {
    par[i] = i;
    rnk[i] = 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 (rnk[x] < rnk[y])
    par[x] = y;
  else {
    par[y] = x;
    if (rnk[x] == rnk[y])
      rnk[x]++;
  }
}

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

int main() {

  int n, m;
  cin >> n >> m;
  int p[n + 1];
  init(n + 1);
  for (int i = 1; i < n + 1; i++)
    cin >> p[i];
  REP(i, m) {
    int x, y;
    cin >> x >> y;
    unite(p[x], p[y]);
  }

  int ans = 0;
  for (int i = 1; i < n + 1; i++) {
    if (same(i, p[i]))
      ans++;
  }

  cout << ans;
  return 0;
}
Problem p03354 (C++)

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

struct UnionFind {
  vector<int> par;

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

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    par[x] = y;
  }

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

int main() {
  int n, m;
  cin >> n >> m;
  int p[n];
  for (int i = 0; i < n; i++)
    cin >> p[i];

  int x, y;
  UnionFind tree(n);
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int answer = 0;
  for (int i = 0; i < n; i++)
    if (tree.same(i, p[i] - 1))
      answer++;
  cout << answer << endl;
  return 0;
}


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

struct UnionFind {
  vector<int> par;

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

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

  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return;
    par[x] = y;
  }

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

int main() {
  int n, m;
  cin >> n >> m;
  int p[n];
  for (int i = 0; i < n; i++)
    cin >> p[i];

  int x, y;
  UnionFind tree(n);
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int answer = 0;
  for (int i = 0; i < n; i++)
    if (tree.same(i, p[i] - 1))
      answer++;
  cout << answer << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define rep(i, z, n) for (int i = z; i < n; i++)
#define all(v) v.begin(), v.end()
typedef long long ll;
// const int INF = 1<<29;
using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

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

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

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

  UnionFind tree(N);

  vector<int> p(N);
  rep(i, 0, N) cin >> p.at(i);
  vector<int> x(M), y(M);
  rep(i, 0, M) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int cnt = 0;
  rep(i, 0, N) {
    if (tree.same(i, p.at(i) - 1))
      cnt++;
  }
  cout << cnt << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define rep(i, z, n) for (int i = z; i < n; i++)
#define all(v) v.begin(), v.end()
typedef long long ll;
// const int INF = 1<<29;
using namespace std;

struct UnionFind {
  vector<int> par;

  UnionFind(int N) : par(N) {
    for (int i = 0; i < N; i++)
      par[i] = i;
  }

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

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

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

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

  UnionFind tree(N);

  vector<int> p(N);
  rep(i, 0, N) cin >> p.at(i);
  vector<int> x(M), y(M);
  rep(i, 0, M) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int cnt = 0;
  rep(i, 0, N) {
    if (tree.same(i, p.at(i) - 1))
      cnt++;
  }
  cout << cnt << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define ll long long int
#define mod_ceil(a, b) (a % b) ? a / b + 1 : a / b
using namespace std;

ll U[100010];

ll root(ll x) {
  while (x != U[x]) {
    x = U[U[x]];
  }
  return x;
}

void Union(ll x, ll y) {
  ll root_x = root(x);
  ll root_y = root(y);
  U[root_x] = root_y;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  ll n, m, x, y;
  cin >> n >> m;
  vector<ll> P(n + 1);
  for (ll i = 1; i <= n; i++) {
    cin >> P[i];
  }
  // initialize dsu
  for (ll i = 1; i <= n; i++) {
    U[i] = i;
  }
  for (ll i = 0; i < m; i++) {
    cin >> x >> y;
    Union(x, y);
  }
  ll ans = 0;
  for (ll i = 1; i <= n; i++) {
    if (root(i) == root(P[i]))
      ans++;
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define ll long long int
#define mod_ceil(a, b) (a % b) ? a / b + 1 : a / b
using namespace std;

ll U[100010];

ll root(ll x) {
  while (x != U[x]) {
    U[x] = U[U[x]];
    x = U[x];
  }
  return x;
}

void Union(ll x, ll y) {
  ll root_x = root(x);
  ll root_y = root(y);
  U[root_x] = root_y;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);

  ll n, m, x, y;
  cin >> n >> m;
  vector<ll> P(n + 1);
  for (ll i = 1; i <= n; i++) {
    cin >> P[i];
  }
  // initialize dsu
  for (ll i = 1; i <= n; i++) {
    U[i] = i;
  }
  for (ll i = 0; i < m; i++) {
    cin >> x >> y;
    Union(x, y);
  }
  ll ans = 0;
  for (ll i = 1; i <= n; i++) {
    if (root(i) == root(P[i]))
      ans++;
  }
  cout << ans << endl;
}
Problem p03354 (C++)

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

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

int main() {
  int n, m;
  cin >> n >> m;
  int p[n];
  UnionFind tree(n);
  rep(i, n) cin >> p[i];
  rep(j, m) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int cnt = 0;
  rep(i, n) {
    if (tree.same(p[i], i) || p[i] == i + 1)
      cnt++;
  }
  cout << cnt << endl;
  return 0;
}

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

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

int main() {
  int n, m;
  cin >> n >> m;
  int p[n];
  UnionFind tree(n);
  rep(i, n) cin >> p[i];
  rep(j, m) {
    int x, y;
    cin >> x >> y;
    tree.unite(x - 1, y - 1);
  }
  int cnt = 0;
  rep(i, n) {
    if (tree.same(p[i] - 1, i))
      cnt++;
  }
  cout << cnt << endl;
  return 0;
}
Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<ll> vec;
typedef vector<vec> vec2;
typedef map<ll, ll> MPll;
typedef set<ll> setl;

template <typename T> struct UnionFindTree {

  vector<T> par;

  UnionFindTree(T n) : par(n) {
    for (int i = 1; i <= n; ++i) {
      par[i] = i;
    }
  }

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

  void unite(T x, T y) {
    if (!same(x, y))
      par[root(x)] = root(par[y]);
  }

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

signed main() {
  ll N, M;
  cin >> N >> M;
  ll p[N + 1];

  UnionFindTree<ll> t(N);

  for (int i = 1; i <= N; ++i) {
    cin >> p[i];
  }

  for (int j = 0; j < M; ++j) {
    ll x, y;
    cin >> x >> y;
    t.unite(x, y);
  }

  ll ans = 0;

  for (int k = 1; k <= N; ++k) {
    if (t.same(p[k], k))
      ans++;
  }

  cout << ans << endl;
}


Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <math.h>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<ll> vec;
typedef vector<vec> vec2;
typedef map<ll, ll> MPll;
typedef set<ll> setl;

template <typename T> struct UnionFindTree {

  vector<T> par;

  UnionFindTree(T n) : par(n + 1) {
    for (int i = 1; i <= n; ++i) {
      par[i] = i;
    }
  }

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

  void unite(T x, T y) {
    if (!same(x, y))
      par[root(x)] = root(par[y]);
  }

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

signed main() {
  ll N, M;
  cin >> N >> M;
  ll p[N + 1];

  UnionFindTree<ll> t(N);

  for (int i = 1; i <= N; ++i) {
    cin >> p[i];
  }

  for (int j = 0; j < M; ++j) {
    ll x, y;
    cin >> x >> y;
    t.unite(x, y);
  }

  ll ans = 0;

  for (int k = 1; k <= N; ++k) {
    if (t.same(p[k], k))
      ans++;
  }

  cout << ans << endl;
}