Problem p03354 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define pie 3.141592653589793238462643383279
#define mod 1000000007
#define INF 1145141919364364
#define all(vec) vec.begin(), vec.end()
#define ggr                                                                    \
  getchar();                                                                   \
  getchar();                                                                   \
  return 0;
#define ll long long
#define P pair<int, int>
#define S second
#define F first
int gcd(int x, int y) {
  if (y == 0)
    return x;
  return gcd(y, x % y);
}
int lcm(int x, int y) { return x / gcd(x, y) * y; }
bool prime(int x) {
  for (int i = 2; i <= sqrt(x); i++) {
    if (x % i == 0)
      return false;
  }
  return true;
}

int kai(int x) {
  if (x == 1)
    return 1;
  return kai(x - 1) * x % mod;
}

int mod_pow(int x, int y, int moder) {
  int res = 1;
  while (y > 0) {
    if (y & 1)
      res = res * x % moder;
    x = x * x % moder;
    y >>= 1;
  }
  return res;
}

int comb(int x, int y) {
  if (y > x)
    return 0;
  if (x == y)
    return 1;
  return kai(x) * mod_pow(kai(x - y), mod - 2, mod) % mod *
         mod_pow(kai(y), mod - 2, mod) % mod;
}

class union_find {
private:
  int par[114514], rank[114514];

public:
  void init(int n) {
    rep(i, n) {
      par[i] = i;
      rank[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 (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) {
    if (find(x) == find(y))
      return true;
    else
      return false;
  }
};

int n, m, p[114514], x, y;
vector<int> ta[114514], wa[114514];
union_find mu;
int cnt, ans;

signed main() {
  cin >> n >> m;
  mu.init(n);
  rep(i, n) cin >> p[i];
  rep(i, m) {
    cin >> x >> y;
    mu.unite(x, y);
  }
  rep(i, n) {
    ta[mu.find(i + 1)].push_back(i + 1);
    wa[mu.find(i + 1)].push_back(p[i]);
  }
  rep(i, 114514) {
    if (ta[i].size()) {
      cnt = 0;
      int k = 0;
      sort(all(ta[i]));
      sort(all(wa[i]));
      rep(j, (int)ta[i].size()) {
        while (ta[i][j] > wa[i][k])
          k++;
        if (ta[i][j] == wa[i][k])
          cnt++;
      }
      ans += cnt;
    }
  }
  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define pie 3.141592653589793238462643383279
#define mod 1000000007
#define INF 1145141919364364
#define all(vec) vec.begin(), vec.end()
#define ggr                                                                    \
  getchar();                                                                   \
  getchar();                                                                   \
  return 0;
#define ll long long
#define P pair<int, int>
#define S second
#define F first
int gcd(int x, int y) {
  if (y == 0)
    return x;
  return gcd(y, x % y);
}
int lcm(int x, int y) { return x / gcd(x, y) * y; }
bool prime(int x) {
  for (int i = 2; i <= sqrt(x); i++) {
    if (x % i == 0)
      return false;
  }
  return true;
}

int kai(int x) {
  if (x == 1)
    return 1;
  return kai(x - 1) * x % mod;
}

int mod_pow(int x, int y, int moder) {
  int res = 1;
  while (y > 0) {
    if (y & 1)
      res = res * x % moder;
    x = x * x % moder;
    y >>= 1;
  }
  return res;
}

int comb(int x, int y) {
  if (y > x)
    return 0;
  if (x == y)
    return 1;
  return kai(x) * mod_pow(kai(x - y), mod - 2, mod) % mod *
         mod_pow(kai(y), mod - 2, mod) % mod;
}

class union_find {
private:
  int par[114514], rank[114514];

public:
  void init(int n) {
    rep(i, n) {
      par[i] = i;
      rank[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 (rank[x] < rank[y])
      par[x] = y;
    else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }
  bool same(int x, int y) {
    if (find(x) == find(y))
      return true;
    else
      return false;
  }
};

int n, m, p[114514], x, y;
vector<int> ta[114514], wa[114514];
union_find mu;
int cnt, ans;

signed main() {
  cin >> n >> m;
  mu.init(n);
  rep(i, n) cin >> p[i];
  rep(i, m) {
    cin >> x >> y;
    mu.unite(x, y);
  }
  rep(i, n) {
    ta[mu.find(i + 1)].push_back(i + 1);
    wa[mu.find(i + 1)].push_back(p[i]);
  }
  rep(i, 114514) {
    if (ta[i].size()) {
      cnt = 0;
      int k = 0;
      sort(all(ta[i]));
      sort(all(wa[i]));
      rep(j, (int)ta[i].size()) {
        while (ta[i][j] > wa[i][k] && k <= (int)wa[i].size() - 2)
          k++;
        if (ta[i][j] == wa[i][k])
          cnt++;
      }
      ans += cnt;
    }
  }
  cout << ans << endl;
}