Problem p03842 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define re(i, a, b) for (int i = (a); i < (b); i++)
#define repd(i, a, b) for (int i = (a); i >= (b); i--)
#define clr(a) memset(a, 0, sizeof(a));
#define il inline
#define sz(a) ((int)o.size())
#define run(x) for (int k = head[x]; k; k = e[k].ne)
#define v e[k].t
#define all(a) o.begin(), o.end()
#define mp make_pair
#define pb push_back
#define w1 first
#define w2 second
#define adm(a, b, c)                                                           \
  {                                                                            \
    a = a + b;                                                                 \
    if (a >= c)                                                                \
      a -= c;                                                                  \
    else if (a < 0)                                                            \
      a += c;                                                                  \
  }
typedef double db;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pa;
const int N = 5e3 + 5, M = 1e7 + 5, INF = 1e9, mod = 1e9 + 7;
const ll linf = 1e18;
const double eps = 1e-8, pi = acos(-1);
il int gmin(int &a, int b) {
  if (a > b)
    a = b;
}
il ll gmin(ll &a, ll b) {
  if (a > b)
    a = b;
}
il int gmax(int &a, int b) {
  if (a < b)
    a = b;
}
il ll gmax(ll &a, ll b) {
  if (a < b)
    a = b;
}
il void read(ll &x) {
  ll f = 1, t = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    t = t * 10 + ch - '0';
    ch = getchar();
  }
  x = t * f;
}
il ll read(ll &x, ll &y) {
  read(x);
  read(y);
}
il void read(int &x) {
  int f = 1, t = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    t = t * 10 + ch - '0';
    ch = getchar();
  }
  x = t * f;
}
il int read(int &x, int &y) {
  read(x);
  read(y);
}
il void read(int &a, int &b, int &c) {
  read(a);
  read(b);
  read(c);
}
il void read(ll &a, ll &b, ll &c) {
  read(a);
  read(b);
  read(c);
}
il int read() {
  int x;
  read(x);
  return x;
}
il ll qpow(ll a, ll b, ll p) {
  ll ret = 1;
  for (; b; b >>= 1, a = a * a % p)
    if (b & 1)
      ret = ret * a % p;
  return ret;
}
il ll qpow(ll a, ll b) {
  ll ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
il ll qmul(ll a, ll b, ll p) {
  ll ret = 0;
  for (; b; b >>= 1, a = (a << 1) % p)
    if (b & 1)
      adm(ret, a, p);
  return ret;
}
il ll qmul(ll a, ll b) {
  ll ret = 0;
  for (; b; b >>= 1, a = (a << 1) % mod)
    if (b & 1)
      adm(ret, a, mod);
  return ret;
}
il void judge() {
  freopen("dato.in", "r", stdin);
  freopen("dato.out", "w", stdout);
}
int n, res = 1, a[N], vis[N], d[N], len[N], cnt[N];
ll f[N];
void gao(int n, int m) {
  ll f1 = 1;
  if (n > 1 && n % 2 == 1)
    f1++;
  f[0] = 1;
  f[1] = f1;
  rep(i, 2, m)(f[i] = f1 * f[i - 1] % mod +
                      f[i - 2] * (i - 1) % mod * n % mod) %= mod;
  res = res * f[m] % mod;
}
int main() {
  read(n);
  rep(i, 1, n) read(a[i]), d[a[i]]++;
  rep(i, 1, n) if (d[i] > 2) return puts("0"), 0;
  rep(i, 1, n) if (!d[i]) {
    int x = i, sz = 0;
    for (; d[x] < 2; x = a[x])
      vis[x] = 1, sz++;
    len[x] = sz;
  }
  rep(i, 1, n) if (!vis[i]) {
    int x;
    vector<int> o;
    for (x = i; !vis[x]; x = a[x])
      vis[x] = 1, o.pb(x);
    if (x != i)
      return puts("0"), 0;
    int isc = 1;
    re(j, 0, o.size()) if (len[o[j]]) isc = 0;
    if (isc)
      cnt[o.size()]++;
    else {
      int tmp = 1;
      repd(j, o.size() - 1, 0) if (!len[o[j]]) tmp++;
      else break;
      re(j, 0, o.size()) if (len[o[j]]) {
        if (len[o[j]] < tmp)
          res = res * 2 % mod;
        if (len[o[j]] > tmp)
          return puts("0"), 0;
        tmp = 1;
      }
      else tmp++;
    }
  }
  rep(i, 1, n) if (cnt[i]) gao(i, cnt[i]);
  cout << res << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define re(i, a, b) for (int i = (a); i < (b); i++)
#define repd(i, a, b) for (int i = (a); i >= (b); i--)
#define clr(a) memset(a, 0, sizeof(a));
#define il inline
#define sz(a) ((int)o.size())
#define run(x) for (int k = head[x]; k; k = e[k].ne)
#define v e[k].t
#define all(a) o.begin(), o.end()
#define mp make_pair
#define pb push_back
#define w1 first
#define w2 second
#define adm(a, b, c)                                                           \
  {                                                                            \
    a = a + b;                                                                 \
    if (a >= c)                                                                \
      a -= c;                                                                  \
    else if (a < 0)                                                            \
      a += c;                                                                  \
  }
typedef double db;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int, int> pa;
const int N = 1e6 + 5, M = 1e7 + 5, INF = 1e9, mod = 1e9 + 7;
const ll linf = 1e18;
const double eps = 1e-8, pi = acos(-1);
il int gmin(int &a, int b) {
  if (a > b)
    a = b;
}
il ll gmin(ll &a, ll b) {
  if (a > b)
    a = b;
}
il int gmax(int &a, int b) {
  if (a < b)
    a = b;
}
il ll gmax(ll &a, ll b) {
  if (a < b)
    a = b;
}
il void read(ll &x) {
  ll f = 1, t = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    t = t * 10 + ch - '0';
    ch = getchar();
  }
  x = t * f;
}
il ll read(ll &x, ll &y) {
  read(x);
  read(y);
}
il void read(int &x) {
  int f = 1, t = 0;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    t = t * 10 + ch - '0';
    ch = getchar();
  }
  x = t * f;
}
il int read(int &x, int &y) {
  read(x);
  read(y);
}
il void read(int &a, int &b, int &c) {
  read(a);
  read(b);
  read(c);
}
il void read(ll &a, ll &b, ll &c) {
  read(a);
  read(b);
  read(c);
}
il int read() {
  int x;
  read(x);
  return x;
}
il ll qpow(ll a, ll b, ll p) {
  ll ret = 1;
  for (; b; b >>= 1, a = a * a % p)
    if (b & 1)
      ret = ret * a % p;
  return ret;
}
il ll qpow(ll a, ll b) {
  ll ret = 1;
  for (; b; b >>= 1, a = a * a % mod)
    if (b & 1)
      ret = ret * a % mod;
  return ret;
}
il ll qmul(ll a, ll b, ll p) {
  ll ret = 0;
  for (; b; b >>= 1, a = (a << 1) % p)
    if (b & 1)
      adm(ret, a, p);
  return ret;
}
il ll qmul(ll a, ll b) {
  ll ret = 0;
  for (; b; b >>= 1, a = (a << 1) % mod)
    if (b & 1)
      adm(ret, a, mod);
  return ret;
}
il void judge() {
  freopen("dato.in", "r", stdin);
  freopen("dato.out", "w", stdout);
}
int n, res = 1, a[N], vis[N], d[N], len[N], cnt[N];
ll f[N];
void gao(int n, int m) {
  ll f1 = 1;
  if (n > 1 && n % 2 == 1)
    f1++;
  f[0] = 1;
  f[1] = f1;
  rep(i, 2, m)(f[i] = f1 * f[i - 1] % mod +
                      f[i - 2] * (i - 1) % mod * n % mod) %= mod;
  res = res * f[m] % mod;
}
int main() {
  read(n);
  rep(i, 1, n) read(a[i]), d[a[i]]++;
  rep(i, 1, n) if (d[i] > 2) return puts("0"), 0;
  rep(i, 1, n) if (!d[i]) {
    int x = i, sz = 0;
    for (; d[x] < 2; x = a[x])
      vis[x] = 1, sz++;
    len[x] = sz;
  }
  rep(i, 1, n) if (!vis[i]) {
    int x;
    vector<int> o;
    for (x = i; !vis[x]; x = a[x])
      vis[x] = 1, o.pb(x);
    if (x != i)
      return puts("0"), 0;
    int isc = 1;
    re(j, 0, o.size()) if (len[o[j]]) isc = 0;
    if (isc)
      cnt[o.size()]++;
    else {
      int tmp = 1;
      repd(j, o.size() - 1, 0) if (!len[o[j]]) tmp++;
      else break;
      re(j, 0, o.size()) if (len[o[j]]) {
        if (len[o[j]] < tmp)
          res = res * 2 % mod;
        if (len[o[j]] > tmp)
          return puts("0"), 0;
        tmp = 1;
      }
      else tmp++;
    }
  }
  rep(i, 1, n) if (cnt[i]) gao(i, cnt[i]);
  cout << res << endl;
}