最后一个捆绑测试里面有几个点WA了。我的思路好像不太一样,我是用错位排序来推的。求 hack 数据。玄关
// Author: chenly8128
// Created: 2025-01-11 17:22:28
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read(void) {
int res = 0;bool flag = true;char c = getchar();
while (c < '0' || c > '9') {flag ^= (c == '-');c = getchar();}
while (c >= '0' && c <= '9') {res = (res << 3) + (res << 1) + (c ^ 48);c = getchar();}
return flag ? res : -res;
}
const int MAXN = 1e6+10;
const int mod = 998244353;
int n,p[MAXN],d[MAXN];
int cnt[MAXN],ghi[MAXN],inv[MAXN];
bool vis[MAXN],b;
vector <int> g[MAXN];
void dfs (int x,int col) {
vis[x] = true;
sort (g[x].begin(),g[x].end());
int sz = unique (g[x].begin(),g[x].end()) - g[x].begin();
cnt[col]++;
if (sz >= 3) {
puts ("0");
exit(0);
}
if (sz <= 1) b = true;
for (int v : g[x]) {
if (sz > 1 && v == x) {
puts ("0");
exit(0);
}
if (!vis[v]) dfs (v,col);
}
}
int power_mod (int x,int k) {
int ans = 1;
while (k) {
if (k&1) ans = ans * x % mod;
x = x * x % mod;
k >>= 1;
}
return ans;
}
int C (int a,int b) {
return ghi[a] * inv[b] % mod * inv[a-b] % mod;
}
signed main (void) {
n = read();
for (int i = 1;i <= n;i++) {
p[i] = read();
g[p[i]].push_back(i);
g[i].push_back(p[i]);
}
int now = 0,k = 0,now2 = 0,m = 0;
int ans = 1;
for (int i = 1;i <= n;i++)
if (!vis[i]) {
b = false;
dfs (i,++now);
if (cnt[now] > 2) {
now2++;
if (b) m++;
}
else if (cnt[now] == 2) k++;
}
ans = power_mod(2,now2);
ghi[0] = inv[0] = 1;
for (int i = 1;i <= n;i++) {
ghi[i] = ghi[i-1] * i % mod;
inv[i] = power_mod(ghi[i],mod-2);
}
d[0] = ghi[m];
for (int i = 1;i <= k;i++)
d[i] = (m+i-1) * (d[i-1] + (i >= 2 ? d[i-2] : 0)) % mod;
int tot = 0;
for (int i = 0;i <= k;i++)
tot = (tot + power_mod(2,k-i) * d[k-i] % mod * C(k,i)) % mod;
printf ("%lld\n",ans * tot % mod);
return 0;
}