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

Buggy submission (status: Runtime Error):
/*

*/
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <ios>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
#define repb(i, a, b) for (int i = a; i < b; i++)
#define MAX_N 10000

using namespace std;
typedef pair<int, int> P;
typedef long long int ll;

const int INF = 1 << 30;
const ll MOD = ll(1e9 + 7);

int parent[MAX_N + 1], depth[MAX_N + 1];

int root(int a) {
  if (parent[a] == a)
    return a;
  return parent[a] = root(parent[a]);
}

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

void unite(int a, int b) {
  a = root(a);
  b = root(b);
  if (depth[a] >= depth[b]) {
    parent[b] = a;
    if (depth[a] == depth[b])
      depth[a]++;
  } else {
    parent[a] = b;
  }
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  rep(i, n) {
    parent[i] = i;
    depth[i] = 0;
  }
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    unite(--x, --y);
  }
  int ans = 0;
  rep(i, n) {
    if (same(p[i], i))
      ans++;
  }
  cout << ans << endl;
  // system("read -n 1 -s -p \"Press any key to continue...\"");
}


Fixed submission:
/*

*/
#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <ios>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
#define repb(i, a, b) for (int i = a; i < b; i++)
#define MAX_N 100000

using namespace std;
typedef pair<int, int> P;
typedef long long int ll;

const int INF = 1 << 30;
const ll MOD = ll(1e9 + 7);

int parent[MAX_N + 1], depth[MAX_N + 1];

int root(int a) {
  if (parent[a] == a)
    return a;
  return parent[a] = root(parent[a]);
}

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

void unite(int a, int b) {
  a = root(a);
  b = root(b);
  if (depth[a] >= depth[b]) {
    parent[b] = a;
    if (depth[a] == depth[b])
      depth[a]++;
  } else {
    parent[a] = b;
  }
}

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  rep(i, n) {
    parent[i] = i;
    depth[i] = 0;
  }
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    unite(--x, --y);
  }
  int ans = 0;
  rep(i, n) {
    if (same(p[i], i))
      ans++;
  }
  cout << ans << endl;
  // system("read -n 1 -s -p \"Press any key to continue...\"");
}
Problem p03356 (C++)

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

int N, M;
vector<int> par;

void initialize() {
  par.resize(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) {
  if (root(x) == root(y)) {
    return;
  } else {
    par[root(x)] = root(y);
  }
}

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

int main() {
  cin >> N >> M;
  int ans = 0;
  vector<int> p(N);
  for (int i = 0; i < N; i++) {
    cin >> p[i];
  }
  initialize();
  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    unite(x, y);
  }

  for (int i = 0; i < N; i++) {
    if (issame(i, p[i])) {
      ans++;
    }
  }

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


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

int N, M;
vector<int> par;

void initialize() {
  par.resize(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) {
  if (root(x) == root(y)) {
    return;
  } else {
    par[root(x)] = root(y);
  }
}

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

int main() {
  cin >> N >> M;
  int ans = 0;
  vector<int> p(N);
  for (int i = 0; i < N; i++) {
    cin >> p[i];
    p[i]--;
  }
  initialize();
  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    unite(x, y);
  }

  for (int i = 0; i < N; i++) {
    if (issame(i, p[i])) {
      ans++;
    }
  }

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

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

const int maxN = 1e3;

#define FORU(i, l, r) for (int i = l; i <= r; ++i)
#define FORD(i, r, l) for (int i = r; i >= l; --i)
#define REPU(i, r) for (int i = 0; i < r; ++i)
#define F first
#define S second
#define PB push_back
#define LL long long
#define BIT(x, i) ((x >> i) & 1)
#define PINT pair<int, int>
#define MP make_pair

int n, m, a[maxN], p[maxN], res;

int get_root(int u) { return (u == p[u]) ? u : (p[u] = get_root(p[u])); }

int main() {
  cin >> n >> m;
  FORU(i, 1, n) p[i] = i, cin >> a[i];
  FORU(i, 1, m) {
    int u, v;
    cin >> u >> v;
    int ru = get_root(u);
    int rv = get_root(v);
    if (ru != rv)
      p[ru] = rv;
  }
  FORU(i, 1, n)
  if (get_root(i) == get_root(a[i]))
    ++res;
  cout << res;
}


Fixed submission:
#include <algorithm>
#include <assert.h>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <vector>

using namespace std;

const int maxN = 1e5 + 10;

#define FORU(i, l, r) for (int i = l; i <= r; ++i)
#define FORD(i, r, l) for (int i = r; i >= l; --i)
#define REPU(i, r) for (int i = 0; i < r; ++i)
#define F first
#define S second
#define PB push_back
#define LL long long
#define BIT(x, i) ((x >> i) & 1)
#define PINT pair<int, int>
#define MP make_pair

int n, m, a[maxN], p[maxN], res;

int get_root(int u) { return (u == p[u]) ? u : (p[u] = get_root(p[u])); }

int main() {
  cin >> n >> m;
  FORU(i, 1, n) p[i] = i, cin >> a[i];
  FORU(i, 1, m) {
    int u, v;
    cin >> u >> v;
    int ru = get_root(u);
    int rv = get_root(v);
    if (ru != rv)
      p[ru] = rv;
  }
  FORU(i, 1, n)
  if (get_root(i) == get_root(a[i]))
    ++res;
  cout << res;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

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

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

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

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N);
  for (int i = 0; i < N; i++)
    cin >> A[i];
  UnionFind Onion(M);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    Onion.unite(a - 1, b - 1);
  }
  int ans = 0;
  for (int i = 0; i < N; i++) {
    if (Onion.same(i, A[i] - 1))
      ans++;
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

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

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

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

  bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
    int rx = root(x);
    int ry = root(y);
    return rx == ry;
  }
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N);
  for (int i = 0; i < N; i++)
    cin >> A[i];
  UnionFind Onion(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    Onion.unite(a - 1, b - 1);
  }
  int ans = 0;
  for (int i = 0; i < N; i++) {
    if (Onion.same(i, A[i] - 1))
      ans++;
  }
  cout << ans << endl;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 1; i <= (int)(n); ++i)
int par[100001];
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
int main() {
  int n, m, x, y, ans = 0;
  scanf("%d%d", &n, &m);
  int p[n + 1];
  rep(i, n) {
    par[i] = i;
    scanf("%d", p[i]);
  }
  rep(i, m) {
    scanf("%d%d", &x, &y);
    x = find(x);
    y = find(y);
    if (x == y)
      continue;
    par[y] = x;
  }
  rep(i, n) {
    if (p[i] == i) {
      ans++;
    } else if (find(p[i]) == find(p[p[i]])) {
      ans++;
    }
  }
  printf("%d", ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 1; i <= (int)(n); ++i)
int par[100001];
int find(int x) {
  if (par[x] == x)
    return x;
  else
    return par[x] = find(par[x]);
}
int main() {
  int n, m, x, y, ans = 0;
  scanf("%d%d", &n, &m);
  int p[n + 1];
  rep(i, n) {
    par[i] = i;
    scanf("%d", &p[i]);
  }
  rep(i, m) {
    scanf("%d%d", &x, &y);
    x = find(x);
    y = find(y);
    if (x == y)
      continue;
    par[y] = x;
  }
  rep(i, n) {
    if (p[i] == i) {
      ans++;
    } else if (find(p[i]) == find(p[p[i]])) {
      ans++;
    }
  }
  printf("%d", ans);
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef long double ld;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define F first
#define S second

const int mx = 100010;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par, sizes; // par[i]:iの親の番号(ex)par[3]=2 : 3の親が2
  UnionFind(int n) : par(n), sizes(n, 1) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int root(int x) { // xが属する木の根を再帰で得る:root(x)={xの木の根}
    if (par[x] == x) {
      return x;
    }
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry) {
      return;
    } // xとyの根が同じ(=同じ木にある)時はそのまま
    if (sizes[rx] < sizes[ry]) {
      swap(rx, ry);
    } // xの木をおおきくする
    par[ry] = rx;
    sizes[rx] += sizes[ry]; // sizes[ry]はもう使わない
  }
  bool check(int x, int y) { // x,yが属する木が同じならtrueを返す
    return root(x) == root(y);
  }
  int size(int x) { // xが含まれる木の大きさを返す
    return sizes[root(x)];
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  rep(i, n) cin >> p[i];
  UnionFind uf(n);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    uf.unite(x, y);
  }
  int ans = 0;
  rep(i, n) {
    if (uf.check(i, p[i]))
      ans++;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
typedef long long ll;
typedef long double ld;
const int inf = 1e9 + 7;
const ll longinf = 1LL << 60;
#define REP(i, m, n) for (int i = (int)(m); i < (int)(n); ++i)
#define rep(i, n) REP(i, 0, n)
#define F first
#define S second

const int mx = 100010;
const ll mod = 1e9 + 7;

struct UnionFind {
  vector<int> par, sizes; // par[i]:iの親の番号(ex)par[3]=2 : 3の親が2
  UnionFind(int n) : par(n), sizes(n, 1) { // 最初は全てが根であるとして初期化
    for (int i = 0; i < n; i++) {
      par[i] = i;
    }
  }
  int root(int x) { // xが属する木の根を再帰で得る:root(x)={xの木の根}
    if (par[x] == x) {
      return x;
    }
    return par[x] = root(par[x]);
  }
  void unite(int x, int y) { // xとyの木を併合
    int rx = root(x);        // xの根をrx
    int ry = root(y);        // yの根をry
    if (rx == ry) {
      return;
    } // xとyの根が同じ(=同じ木にある)時はそのまま
    if (sizes[rx] < sizes[ry]) {
      swap(rx, ry);
    } // xの木をおおきくする
    par[ry] = rx;
    sizes[rx] += sizes[ry]; // sizes[ry]はもう使わない
  }
  bool check(int x, int y) { // x,yが属する木が同じならtrueを返す
    return root(x) == root(y);
  }
  int size(int x) { // xが含まれる木の大きさを返す
    return sizes[root(x)];
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> p(n);
  rep(i, n) {
    cin >> p[i];
    p[i]--;
  }
  UnionFind uf(n);
  rep(i, m) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    uf.unite(x, y);
  }
  int ans = 0;
  rep(i, n) {
    if (uf.check(i, p[i]))
      ans++;
  }
  cout << ans << endl;
  return 0;
}
Problem p03356 (C++)

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

#define INF 100100100
#define MOD 1000000007

using namespace std;
using ll = long long;
using ull = unsigned long long;

vector<ll> par;
vector<ll> height;

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

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

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

void merge(int x, int y) {
  if (isSame(x, y))
    return;

  x = root(x);
  y = root(y);
  if (height[x] < height[y])
    swap(x, y);

  par[y] = x;
  if (height[x] == height[y])
    height[y]++;
}

int main(int argc, char const *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int N, M;
  cin >> N >> M;
  vector<int> p(N);
  init(N + 1);
  for (int i = 0; i < N; i++)
    cin >> p[i];
  int x = 0, y = 0;
  for (int i = 0; i < M; i++) {
    cin >> x >> y;
    merge(x, y);
    merge(y, x);
  }
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    if (isSame(p[i], i + 1))
      ans++;
  }
  cout << ans << endl;
  return 0;
}


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

#define INF 100100100
#define MOD 1000000007

using namespace std;
using ll = long long;
using ull = unsigned long long;

vector<ll> par;
vector<ll> height;

void init(int n) {
  height.resize(n, 0);
  par.resize(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]);
}

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

void merge(int x, int y) {
  if (isSame(x, y))
    return;

  x = root(x);
  y = root(y);
  if (height[x] < height[y])
    swap(x, y);

  par[y] = x;
  if (height[x] == height[y])
    height[y]++;
}

int main(int argc, char const *argv[]) {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int N, M;
  cin >> N >> M;
  vector<int> p(N);
  init(N + 1);
  for (int i = 0; i < N; i++)
    cin >> p[i];
  int x = 0, y = 0;
  for (int i = 0; i < M; i++) {
    cin >> x >> y;
    merge(x, y);
    merge(y, x);
  }
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    if (isSame(p[i], i + 1))
      ans++;
  }
  cout << ans << endl;
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Time Limit Exceeded):
#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) { 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)
      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;
  vector<int> p(n);
  for (auto &&x : p)
    cin >> x;
  int x, y;
  UnionFind uf(n);
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    uf.unite(x - 1, y - 1);
  }
  int sum = 0;
  for (int i = 0; i < n; i++) {
    if (uf.same(i, p[i] - 1))
      sum++;
  }
  cout << sum << 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) { return par[x] == x ? x : 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;
  vector<int> p(n);
  for (auto &&x : p)
    cin >> x;
  int x, y;
  UnionFind uf(n);
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    uf.unite(x - 1, y - 1);
  }
  int sum = 0;
  for (int i = 0; i < n; i++) {
    if (uf.same(i, p[i] - 1))
      sum++;
  }
  cout << sum << endl;
  return 0;
}
Problem p03356 (C++)

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

using namespace std;

typedef long long ll;
typedef double long dl;
typedef pair<int, int> pii;
typedef pair<pii, pii> p2i;
const int maxn = (int)1e5 + 2;
const int mod = (int)1e9 + 7;
const ll inf = (ll)1e18;

#define fi first
#define se second
#define acel ios_base ::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define next continue
#define getsz(x) (int)log10(x)

int n, m;
int a[maxn];
int x, y, t;
int u[maxn];
vector<int> g[maxn];
set<int> w[maxn];
void dfs(int v, int p) {
  u[v] = t;
  w[t].insert(a[v]);
  for (int i : g[v]) {
    if (i == p) {
      next;
    }
    dfs(i, v);
  }
}

int ans;
int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= m; i++) {
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) {
    if (a[i] == i) {
      ans++;
      next;
    }
    if (!u[i]) {
      t++;
      dfs(i, i);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (i == a[i]) {
      next;
    }
    ans += w[u[i]].count(i);
  }
  cout << ans;
}


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

using namespace std;

typedef long long ll;
typedef double long dl;
typedef pair<int, int> pii;
typedef pair<pii, pii> p2i;
const int maxn = (int)1e5 + 2;
const int mod = (int)1e9 + 7;
const ll inf = (ll)1e18;

#define fi first
#define se second
#define acel ios_base ::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define next continue
#define getsz(x) (int)log10(x)

int n, m;
int a[maxn];
int x, y, t;
int u[maxn];
vector<int> g[maxn];
set<int> w[maxn];
void dfs(int v, int p) {
  u[v] = t;
  w[t].insert(a[v]);
  for (int i : g[v]) {
    if (i == p) {
      next;
    }
    if (!u[i]) {
      dfs(i, v);
    }
  }
}

int ans;
int main() {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= m; i++) {
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) {
    if (a[i] == i) {
      ans++;
      next;
    }
    if (!u[i]) {
      t++;
      dfs(i, i);
    }
  }
  for (int i = 1; i <= n; i++) {
    if (i == a[i]) {
      next;
    }
    ans += w[u[i]].count(i);
  }
  cout << ans;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

typedef int INT;
#define int long long

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

  vector<int> g[10001];

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

  int b, c;
  for (int i = 0; i < m; i++) {
    cin >> b >> c;
    g[b - 1].push_back(c - 1);
    g[c - 1].push_back(b - 1);
  }
  vector<bool> used(n);
  int sum = 0;
  for (int i = 0; i < n; i++) {

    if (!used[i]) {
      vector<int> pos, in;
      used[i] = true;
      queue<int> q;
      q.push(i);
      while (!q.empty()) {
        int v = q.front();
        q.pop();
        pos.push_back(v);
        in.push_back(a[v]);
        for (int j = 0; j < g[v].size(); j++) {
          if (!used[g[v][j]]) {
            used[g[v][j]] = true;
            q.push(g[v][j]);
          }
        }
      }

      sort(in.begin(), in.end());
      for (int j = 0; j < pos.size(); j++) {
        sum += upper_bound(in.begin(), in.end(), pos[j]) -
               lower_bound(in.begin(), in.end(), pos[j]);
      }
    }
  }
  cout << sum;
  return 0;
}

Fixed submission:
#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

typedef int INT;
#define int long long

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

  vector<int> g[100001];

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

  int b, c;
  for (int i = 0; i < m; i++) {
    cin >> b >> c;
    g[b - 1].push_back(c - 1);
    g[c - 1].push_back(b - 1);
  }
  vector<bool> used(n);
  int sum = 0;
  for (int i = 0; i < n; i++) {

    if (!used[i]) {
      vector<int> pos, in;
      used[i] = true;
      queue<int> q;
      q.push(i);
      while (!q.empty()) {
        int v = q.front();
        q.pop();
        pos.push_back(v);
        in.push_back(a[v]);
        for (int j = 0; j < g[v].size(); j++) {
          if (!used[g[v][j]]) {
            used[g[v][j]] = true;
            q.push(g[v][j]);
          }
        }
      }

      sort(in.begin(), in.end());
      for (int j = 0; j < pos.size(); j++) {
        sum += upper_bound(in.begin(), in.end(), pos[j]) -
               lower_bound(in.begin(), in.end(), pos[j]);
      }
    }
  }
  cout << sum;
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
vector<int> e[111111];
int a[111111];
vector<int> b;
bool vis[111111];
void dfs(int x) {
  b.push_back(x);
  vis[x] = 1;
  for (int i = 0; i < e[x].size(); i++) {
    int v = e[x][i];
    if (!vis[v])
      continue;
    dfs(v);
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    e[u].push_back(v);
    e[v].push_back(u);
  }
  memset(vis, 0, sizeof(vis));
  map<int, int> mp;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      b.clear();
      mp.clear();
      dfs(i);
      for (int j = 0; j < b.size(); j++) {
        mp[a[b[j]]] = 1;
      }
      for (int j = 0; j < b.size(); j++) {
        if (mp[b[j]] == 1)
          ans++;
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
vector<int> e[111111];
int a[111111];
vector<int> b;
bool vis[111111];
void dfs(int x) {
  b.push_back(x);
  vis[x] = 1;
  for (int i = 0; i < e[x].size(); i++) {
    int v = e[x][i];
    if (vis[v])
      continue;
    dfs(v);
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
  }
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    e[u].push_back(v);
    e[v].push_back(u);
  }
  memset(vis, 0, sizeof(vis));
  map<int, int> mp;
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    if (!vis[i]) {
      b.clear();
      mp.clear();
      dfs(i);
      for (int j = 0; j < b.size(); j++) {
        mp[a[b[j]]] = 1;
      }
      for (int j = 0; j < b.size(); j++) {
        if (mp[b[j]] == 1)
          ans++;
      }
    }
  }
  printf("%d\n", ans);
  return 0;
}
Problem p03356 (C++)

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

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> which_set(n, 0);
  vector<vector<pair<int, int>>> sets(n);
  for (int i = 0, p; i < n; ++i) {
    cin >> p;
    --p;
    sets[i].emplace_back(i, p);
    which_set[i] = i;
  }

  for (int i = 0, x, y; i < m; ++i) {
    cin >> x >> y;
    --x, --y;
    x = which_set[x];
    y = which_set[y];
    if (sets[x].size() > sets[y].size())
      swap(x, y);
    for (auto p : sets[x]) {
      which_set[p.first] = y;
      sets[y].push_back(p);
    }
    sets[x].clear();
  }

  int rez = 0;

  for (auto &x : sets) {
    vector<int> s1, s2;
    for (auto &y : x)
      s1.push_back(y.first), s2.push_back(y.second);

    sort(begin(s1), end(s1));
    sort(begin(s2), end(s2));

    vector<int> tmp;
    set_intersection(begin(s1), end(s1), begin(s2), end(s2),
                     back_inserter(tmp));

    rez += tmp.size();
  }

  cout << rez << endl;
  return 0;
}


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

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> which_set(n, 0);
  vector<vector<pair<int, int>>> sets(n);
  for (int i = 0, p; i < n; ++i) {
    cin >> p;
    --p;
    sets[i].emplace_back(i, p);
    which_set[i] = i;
  }

  for (int i = 0, x, y; i < m; ++i) {
    cin >> x >> y;
    --x, --y;
    x = which_set[x];
    y = which_set[y];
    if (x == y)
      continue;
    if (sets[x].size() > sets[y].size())
      swap(x, y);
    for (auto p : sets[x]) {
      which_set[p.first] = y;
      sets[y].push_back(p);
    }
    sets[x].clear();
  }

  int rez = 0;

  for (auto &x : sets) {
    vector<int> s1, s2;
    for (auto &y : x)
      s1.push_back(y.first), s2.push_back(y.second);

    sort(begin(s1), end(s1));
    sort(begin(s2), end(s2));

    vector<int> tmp;
    set_intersection(begin(s1), end(s1), begin(s2), end(s2),
                     back_inserter(tmp));

    rez += tmp.size();
  }

  cout << rez << endl;
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
// #define int long long
#define re(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin, v.end()
using namespace std;
typedef pair<int, int> P;
struct UnionFind {
  int n;
  vector<int> r, p;
  UnionFind() {}
  UnionFind(int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  int find(int x) { return (x == p[x] ? x : p[x] = find(p[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 (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }
};

int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
int n, m;
vector<P> v[100005];
int ans, x, y;

signed main() {
  cin >> n >> m;
  int a[n];
  UnionFind U(n + 10);
  re(i, n) cin >> a[i];
  re(i, m) {
    cin >> x >> y;
    x--;
    y--;
    U.unite(x, y);
  }
  re(i, n) { v[U.find(i)].push_back(P(i, a[i])); }
  re(i, n + 10) {
    set<int> st;
    re(j, v[i].size()) {
      st.insert(v[i][j].first + 1);
      st.insert(v[i][j].second);
    }
    int x = v[i].size() * 2;
    ans += (x - st.size());
  }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
// #define int long long
#define re(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin, v.end()
using namespace std;
typedef pair<int, int> P;
struct UnionFind {
  int n;
  vector<int> r, p;
  UnionFind() {}
  UnionFind(int sz) : n(sz), r(sz, 1), p(sz, 0) { iota(p.begin(), p.end(), 0); }
  int find(int x) { return (x == p[x] ? x : p[x] = find(p[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 (r[x] < r[y])
      swap(x, y);
    r[x] += r[y];
    p[y] = x;
  }
};

int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
int n, m;
vector<P> v[100090];
int ans, x, y;

signed main() {
  cin >> n >> m;
  int a[n];
  UnionFind U(n + 10);
  re(i, n) cin >> a[i];
  re(i, m) {
    cin >> x >> y;
    x--;
    y--;
    U.unite(x, y);
  }
  re(i, n) { v[U.find(i)].push_back(P(i, a[i])); }
  re(i, n + 10) {
    set<int> st;
    re(j, v[i].size()) {
      st.insert(v[i][j].first + 1);
      st.insert(v[i][j].second);
    }
    int x = v[i].size() * 2;
    ans += (x - st.size());
  }
  cout << ans << endl;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
/*
problem's name:
statue:
writer:Patrick_y
*/
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
#define mp make_pair
typedef long long ll;
using namespace std;
const int INF = 20050208;
/*------------main part------------*/

int p[10005];
vector<int> edg[10005];
bool vis[10005];
int num[10005];
int cnt;
int ans;
void dfs(int x) {
  if (vis[x])
    return;
  vis[x] = true;
  num[x] = cnt;
  for (int i = 0; i < edg[x].size(); i++) {
    dfs(edg[x][i]);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    p[i]--;
  }
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    edg[x].push_back(y);
    edg[y].push_back(x);
  }
  for (int i = 0; i < n; i++) {
    if (!vis[i]) {
      dfs(i);
      cnt++;
    }
  }
  for (int i = 0; i < n; i++) {
    if (num[i] == num[p[i]]) {
      ans++;
    }
  }
  cout << ans;
  return 0;
}


Fixed submission:
/*
problem's name:
statue:
writer:Patrick_y
*/
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <utility>
#include <vector>
#define mp make_pair
typedef long long ll;
using namespace std;
const int INF = 20050208;
/*------------main part------------*/

int p[100005];
vector<int> edg[100005];
bool vis[100005];
int num[100005];
int cnt;
int ans;
void dfs(int x) {
  if (vis[x])
    return;
  vis[x] = true;
  num[x] = cnt;
  for (int i = 0; i < edg[x].size(); i++) {
    dfs(edg[x][i]);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    p[i]--;
  }
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    edg[x].push_back(y);
    edg[y].push_back(x);
  }
  for (int i = 0; i < n; i++) {
    if (!vis[i]) {
      dfs(i);
      cnt++;
    }
  }
  for (int i = 0; i < n; i++) {
    if (num[i] == num[p[i]]) {
      ans++;
    }
  }
  cout << ans;
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using lint = long long;
std::vector<lint> p;
lint find(lint x) { return p.at(x) < 0 ? x : p.at(x) = find(p.at(x)); }
void unite(lint x, lint y) { x = find(x), y = find(y), p.at(x) = y; }
int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout.setf(std::ios_base::fixed);
  std::cout.precision(15);
  lint n, m;
  std::cin >> n >> m;
  std::vector<lint> a(n);
  for (lint i = 0; i < n; i++) {
    std::cin >> a.at(i);
    a.at(i)--;
  }
  p.resize(n, -1);
  while (m--) {
    lint u, v;
    std::cin >> u >> v;
    u--, v--;
    unite(u, v);
  }
  lint ans = 0;
  for (lint i = 0; i < n; i++) {
    ans += find(i) == find(a.at(i));
  }
  std::cout << ans << '\n';
}


Fixed submission:
#include <bits/stdc++.h>
using lint = long long;
std::vector<lint> p;
lint find(lint x) { return p.at(x) < 0 ? x : p.at(x) = find(p.at(x)); }
void unite(lint x, lint y) {
  x = find(x), y = find(y);
  if (x != y)
    p.at(x) = y;
}
int main() {
  std::cin.tie(nullptr);
  std::ios_base::sync_with_stdio(false);
  std::cout.setf(std::ios_base::fixed);
  std::cout.precision(15);
  lint n, m;
  std::cin >> n >> m;
  std::vector<lint> a(n);
  for (lint i = 0; i < n; i++) {
    std::cin >> a.at(i);
    a.at(i)--;
  }
  p.resize(n, -1);
  while (m--) {
    lint u, v;
    std::cin >> u >> v;
    u--, v--;
    unite(u, v);
  }
  lint ans = 0;
  for (lint i = 0; i < n; i++) {
    ans += find(i) == find(a.at(i));
  }
  std::cout << ans << '\n';
}
Problem p03356 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

#define N 110000

vector<int> vec[N];
int order[N];
int a[N], pa[N];

void init(int n) {
  memset(order, 0, sizeof(order));
  for (int i = 1; i <= n; ++i) {
    pa[i] = i;
    vec[i].clear();
    vec[i].push_back(a[i]);
  }
}

int findset(int x) { return x == pa[x] ? pa[x] : pa[x] = findset(pa[x]); }

int main() {
  int n, m;
  while (scanf("%d%d", &n, &m) == 2) {
    for (int i = 1; i <= n; ++i)
      scanf("%d", &a[i]);
    init(n);
    while (m--) {
      int u, v;
      scanf("%d%d", &u, &v);
      int x = findset(u);
      int y = findset(v);
      if (x != y) {
        pa[x] = y;
        for (int i = 0; i < vec[x].size(); ++i) {
          vec[y].push_back(vec[x][i]);
        }
      }
    }
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
      int x = findset(i);
      if (!order[x]) {
        sort(vec[x].begin(), vec[x].end());
        order[x] = 1;
      }
      int p = lower_bound(vec[x].begin(), vec[x].end(), i) - vec[x].begin();
      if (vec[x][p] == i)
        cnt++;
    }
    printf("%d\n", cnt);
  }
  return 0;
}


Fixed submission:
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;

#define N 110000

vector<int> vec[N];
int order[N];
int a[N], pa[N];

void init(int n) {
  memset(order, 0, sizeof(order));
  for (int i = 1; i <= n; ++i) {
    pa[i] = i;
    vec[i].clear();
    vec[i].push_back(a[i]);
  }
}

int findset(int x) { return x == pa[x] ? pa[x] : pa[x] = findset(pa[x]); }

int main() {
  int n, m;
  while (scanf("%d%d", &n, &m) == 2) {
    for (int i = 1; i <= n; ++i)
      scanf("%d", &a[i]);
    init(n);
    while (m--) {
      int u, v;
      scanf("%d%d", &u, &v);
      int x = findset(u);
      int y = findset(v);
      if (x != y) {

        if (vec[x].size() <= vec[y].size()) {
          pa[x] = y;
          for (int i = 0; i < vec[x].size(); ++i) {
            vec[y].push_back(vec[x][i]);
          }
        } else {
          pa[y] = x;
          for (int i = 0; i < vec[y].size(); ++i) {
            vec[x].push_back(vec[y][i]);
          }
        }
      }
    }
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
      int x = findset(i);
      if (!order[x]) {
        sort(vec[x].begin(), vec[x].end());
        order[x] = 1;
      }
      int p = lower_bound(vec[x].begin(), vec[x].end(), i) - vec[x].begin();
      if (vec[x][p] == i)
        cnt++;
    }
    printf("%d\n", cnt);
  }
  return 0;
}
Problem p03356 (C++)

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

struct UnionFind {
  vector<int> data;
  UnionFind(int sz) { data.assign(sz, -1); }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return false;
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }
  int size(int k) { return -data[find(k)]; }
};

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

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

struct UnionFind {
  vector<int> data;
  UnionFind(int sz) { data.assign(sz, -1); }
  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return false;
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }
  int size(int k) { return -data[find(k)]; }
};

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

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define N 100010
using namespace std;
int n, m;
int a[N];
int f[N];
inline int Get(int u) { return u == f[u] ? u : Get(f[u]); }
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i)
    f[i] = i;
  while (m--) {
    int u, v;
    scanf("%d%d", &u, &v);
    int fu = Get(u), fv = Get(v);
    if (fu != fv)
      f[fu] = fv;
  }
  int cnt = 0;
  for (int i = 1; i <= n; ++i) {
    int fu = Get(a[i]);
    int fv = Get(i);
    cnt += (fu == fv);
  }
  printf("%d", cnt);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define N 100010
using namespace std;
int n, m;
int a[N];
int f[N];
inline int Get(int u) { return u == f[u] ? u : f[u] = Get(f[u]); }
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%d", &a[i]);
  for (int i = 1; i <= n; ++i)
    f[i] = i;
  while (m--) {
    int u, v;
    scanf("%d%d", &u, &v);
    int fu = Get(u), fv = Get(v);
    if (fu != fv)
      f[fu] = fv;
  }
  int cnt = 0;
  for (int i = 1; i <= n; ++i) {
    int fu = Get(a[i]);
    int fv = Get(i);
    cnt += (fu == fv);
  }
  printf("%d", cnt);
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 1LL << 62
#define inf 1000000007
const int MAX = 510000;
const int MOD = 1000000007;

ll a[100010];
ll c[100010];
vector<vector<ll>> b(100010);
void dep(ll now, ll p, ll root) {
  c[now] = root;
  if (b[now].size() == 1 && b[now][0] == p) {
    return;
  }
  for (int i = 0; i < b[now].size(); i++) {
    ll next = b[now][i];
    if (next == p) {
      continue;
    }
    dep(next, now, root);
  }
}

int main() {
  ll n, m;
  cin >> n >> m;
  for (int i = 0; i < 100010; i++) {
    c[i] = -1;
  }
  for (int i = 0; i < n; i++) {
    ll x;
    cin >> x;
    x--;
    a[i] = x;
  }
  for (int i = 0; i < m; i++) {
    ll x, y;
    cin >> x >> y;
    x--;
    y--;
    b[x].push_back(y);
    b[y].push_back(x);
  }
  for (int i = 0; i < 100010; i++) {
    if (c[i] != -1) {
      continue;
    }
    dep(i, -1, i);
  }
  ll ans = 0;
  for (int i = 0; i < n; i++) {
    ll now = a[i];
    if (i == now) {
      ans++;
      continue;
    }
    ll root = c[now];
    if (root == c[i]) {
      ans++;
    }
  }
  cout << ans;
  // your code goes here
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define INF 1LL << 62
#define inf 1000000007
const int MAX = 510000;
const int MOD = 1000000007;

ll a[100010];
ll c[100010];
vector<vector<ll>> b(100010);
void dep(ll now, ll p, ll root) {
  c[now] = root;
  if (b[now].size() == 1 && b[now][0] == p) {
    return;
  }
  for (int i = 0; i < b[now].size(); i++) {
    ll next = b[now][i];
    if (next == p || c[next] != -1) {
      continue;
    }
    dep(next, now, root);
  }
}

int main() {
  ll n, m;
  cin >> n >> m;
  for (int i = 0; i < 100010; i++) {
    c[i] = -1;
  }
  for (int i = 0; i < n; i++) {
    ll x;
    cin >> x;
    x--;
    a[i] = x;
  }
  for (int i = 0; i < m; i++) {
    ll x, y;
    cin >> x >> y;
    x--;
    y--;
    b[x].push_back(y);
    b[y].push_back(x);
  }
  for (int i = 0; i < 100010; i++) {
    if (c[i] != -1) {
      continue;
    }
    dep(i, -1, i);
  }
  ll ans = 0;
  for (int i = 0; i < n; i++) {
    ll now = a[i];
    if (i == now) {
      ans++;
      continue;
    }
    ll root = c[now];
    if (root == c[i]) {
      ans++;
    }
  }
  cout << ans;
  // your code goes here
  return 0;
}
Problem p03356 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
const int maxn = 5e3 + 10;
int n, m, x, y;
int fa[maxn], a[maxn];
int find_fa(int x) { return x == fa[x] ? x : fa[x] = find_fa(fa[x]); }
void Union(int x, int y) {
  x = find_fa(x);
  y = find_fa(y);
  if (x != y)
    fa[x] = y;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    fa[i] = i;
    scanf("%d", &a[i]);
  }

  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &x, &y);
    Union(a[x], a[y]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int x = find_fa(i);
    int y = find_fa(a[i]);
    if (x == y)
      ans++;
  }
  printf("%d\n", ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
using namespace std;
const int maxn = 1e5 + 10;
int n, m, x, y;
int fa[maxn], a[maxn];
int find_fa(int x) { return x == fa[x] ? x : fa[x] = find_fa(fa[x]); }
void Union(int x, int y) {
  x = find_fa(x);
  y = find_fa(y);
  if (x != y)
    fa[x] = y;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    fa[i] = i;
    scanf("%d", &a[i]);
  }

  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &x, &y);
    Union(a[x], a[y]);
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    int x = find_fa(i);
    int y = find_fa(a[i]);
    if (x == y)
      ans++;
  }
  printf("%d\n", ans);
  return 0;
}
Problem p03356 (C++)

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

using namespace std;

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

  // 頂点aが所属するグループを調べる
  int root(int a) {
    if (uni[a] < 0)
      return a;
    return uni[a] = root(uni[a]);
  }

  // 頂点aと頂点bを繋ぐ。もともと同じグループの時falseを返す
  bool connect(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return false;

    if (uni[a] > uni[b]) {
      a ^= b;
      b ^= a;
      a ^= b;
    }

    uni[a] = uni[a] + uni[b];
    uni[b] = a;
    return true;
  }

  // 頂点a,bが同じグループであるかを調べる
  bool isConnect(int a, int b) { return root(a) == root(b); }

  // 頂点aを含むグループの頂点数を調べる
  int size(int a) { return -uni[root(a)]; }
};

int main() {

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

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

  UnionFind u(n);
  int x, y;

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

  int ans = 0;

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

  cout << ans << endl;

  return 0;
}


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

using namespace std;

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

  // 頂点aが所属するグループを調べる
  int root(int a) {
    if (uni[a] < 0)
      return a;
    return uni[a] = root(uni[a]);
  }

  // 頂点aと頂点bを繋ぐ。もともと同じグループの時falseを返す
  bool connect(int a, int b) {
    a = root(a);
    b = root(b);
    if (a == b)
      return false;

    if (uni[a] > uni[b]) {
      a ^= b;
      b ^= a;
      a ^= b;
    }

    uni[a] = uni[a] + uni[b];
    uni[b] = a;
    return true;
  }

  // 頂点a,bが同じグループであるかを調べる
  bool isConnect(int a, int b) { return root(a) == root(b); }

  // 頂点aを含むグループの頂点数を調べる
  int size(int a) { return -uni[root(a)]; }
};

int main() {

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

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

  UnionFind u(n + 1);
  int x, y;

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

  int ans = 0;

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

  cout << ans << endl;

  return 0;
}
Problem p03356 (C++)

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

using namespace std;

struct union_find {
  vector<int> par, sz;

  union_find(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; i++)
      par[i] = i, sz[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;

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

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

int main() {
  int n, m;
  cin >> n >> m;
  union_find u(n);
  int *p = new int[n];
  for (int i = 0; i < n; i++)
    cin >> p[i];
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    u.unite(x, y);
  }

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

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

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

using namespace std;

struct union_find {
  vector<int> par, sz;

  union_find(int n) {
    par.resize(n);
    sz.resize(n);
    for (int i = 0; i < n; i++)
      par[i] = i, sz[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;

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

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

int main() {
  int n, m;
  cin >> n >> m;
  union_find u(n);
  int *p = new int[n];
  for (int i = 0; i < n; i++)
    cin >> p[i];
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    u.unite(x, y);
  }

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

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

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;

const int MAX = 100010;

int parent(int uft[], int child) {
  if (uft[child] == -1)
    return child;
  return uft[child] = parent(uft, uft[child]);
}

int main() {
  int N, M;
  int p[MAX];

  int uft[MAX];
  for (int i = 0; i < MAX; i++)
    uft[i] = -1;

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

  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;

    int p1 = parent(uft, x - 1);
    int p2 = parent(uft, y - 1);
    uft[p1] = p2;
  }

  int ans = 0;
  for (int i = 0; i < N; i++) {
    int p1 = parent(uft, p[i] - 1);
    int p2 = parent(uft, i);
    if (p1 == p2)
      ans++;
  }

  cout << ans << endl;

  return 0;
}

Fixed submission:
#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;

const int MAX = 100010;

int parent(int uft[], int child) {
  if (uft[child] == -1)
    return child;
  return uft[child] = parent(uft, uft[child]);
}

int main() {
  int N, M;
  int p[MAX];

  int uft[MAX];
  for (int i = 0; i < MAX; i++)
    uft[i] = -1;

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

  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;

    int p1 = parent(uft, x - 1);
    int p2 = parent(uft, y - 1);
    if (p1 != p2)
      uft[p1] = p2;
  }

  int ans = 0;
  for (int i = 0; i < N; i++) {
    int p1 = parent(uft, p[i] - 1);
    int p2 = parent(uft, i);
    if (p1 == p2)
      ans++;
  }

  cout << ans << endl;

  return 0;
}