Problem p03356 (C++)

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

typedef long long LL;

#define __m int mid = (l + r) >> 1;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1

#define rep(i, a, b) for (register int i = (a); i < (b); i++)
#define per(i, a, b) for (register int i = (a); i > (b); i--)
#define mem(a) memset(a, 0, sizeof(a));
#define pb push_back
#define read2(a, b) read(a) && read(b)

#ifdef LOCAL
#define bug(x) cout << #x << " : " << x << endl;
#else
#define bug(x) ;
#endif

template <class T> inline bool read(T &num) {
  char in;
  bool IsN = false;
  while (in = getchar(), in != '-' && (in < '0' || in > '9'))
    if (in == EOF)
      return false;
  in == '-' ? (IsN = true, num = 0) : num = in - '0';
  while (in = getchar(), in >= '0' && in <= '9')
    num = num * 10 + in - '0';
  return IsN ? num = -num : num, true;
}

const int maxn = 3e5 + 7;
const int inf = 2e9 + 7;
const int mod = 1e9 + 7;

int fa[maxn], num[maxn], pos[maxn];
void init() { rep(i, 0, maxn) fa[i] = i; }
int find(int x) { return fa[x] == x ? x : find(fa[x]); }
void merge(int x, int y) {
  int fx = find(x), fy = find(y);
  if (fx == fy)
    return;
  fa[fx] = fy;
}
int main() {
#ifdef LOCAL
  // freopen("sample.in","r",stdin);
#endif
  ios::sync_with_stdio(false);
  int n, m;
  read2(n, m);
  rep(i, 1, n + 1) {
    int k;
    read(k);
    pos[k] = i;
    num[i] = k;
  }
  init();
  while (m--) {
    int a, b;
    read2(a, b);
    merge(a, b);
  }
  rep(i, 1, n + 1) {
    if (find(i) == find(pos[i])) {
      swap(pos[i], pos[num[i]]);
      swap(num[i], num[pos[num[i]]]);
    }
  }
  int ans = 0;
  rep(i, 1, n + 1) if (num[i] == i) ans++;
  cout << ans << endl;
  return 0;
}


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

typedef long long LL;

#define __m int mid = (l + r) >> 1;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1

#define rep(i, a, b) for (register int i = (a); i < (b); i++)
#define per(i, a, b) for (register int i = (a); i > (b); i--)
#define mem(a) memset(a, 0, sizeof(a));
#define pb push_back
#define read2(a, b) read(a) && read(b)

#ifdef LOCAL
#define bug(x) cout << #x << " : " << x << endl;
#else
#define bug(x) ;
#endif

template <class T> inline bool read(T &num) {
  char in;
  bool IsN = false;
  while (in = getchar(), in != '-' && (in < '0' || in > '9'))
    if (in == EOF)
      return false;
  in == '-' ? (IsN = true, num = 0) : num = in - '0';
  while (in = getchar(), in >= '0' && in <= '9')
    num = num * 10 + in - '0';
  return IsN ? num = -num : num, true;
}

const int maxn = 3e5 + 7;
const int inf = 2e9 + 7;
const int mod = 1e9 + 7;

int fa[maxn], num[maxn], pos[maxn];
void init() { rep(i, 0, maxn) fa[i] = i; }
int find(int x) { return fa[x] = (fa[x] == x) ? x : find(fa[x]); }
void merge(int x, int y) {
  int fx = find(x), fy = find(y);
  if (fx == fy)
    return;
  fa[fx] = fy;
}
int main() {
#ifdef LOCAL
  // freopen("sample.in","r",stdin);
#endif
  ios::sync_with_stdio(false);
  int n, m;
  read2(n, m);
  rep(i, 1, n + 1) {
    int k;
    read(k);
    pos[k] = i;
    num[i] = k;
  }
  init();
  while (m--) {
    int a, b;
    read2(a, b);
    merge(a, b);
  }
  rep(i, 1, n + 1) {
    if (find(i) == find(pos[i])) {
      swap(pos[i], pos[num[i]]);
      swap(num[i], num[pos[num[i]]]);
    }
  }
  int ans = 0;
  rep(i, 1, n + 1) if (num[i] == i) ans++;
  cout << ans << endl;
  return 0;
}