题解 ARC171B【Chmax】
考察题面中的操作究竟做了什么,不难发现其实是将所有满足 \(P_i > i\) 的 \(i\to P_i\) 连边,得到若干条链,然后 \(B_i\) 即为 \(i\) 所在链的最后一个节点。
显然,存在 \(A_i < i\) 时无解,存在 \(A_i\ne i\) 但 \(A_j = i\) 时也无解。
否则,每个 \(A_i\ne i\) 的位置填的数都唯一确定了(必须是下一个满足 \(A_j=A_i\) 的 \(j\)),只需计算将剩下的数填入 \(P\) 中,且满足 \(P_i < i\) 的方案数。这个是十分容易的。具体来说就是从小到大枚举 \(i\),统计有多少个不超过 \(i\) 的数还没有用过,然后如果当前位置需要填一个数,就从这些数中选择一个填入,乘法原理统计即可。
typedef Modint<998244353> mint;
int n, a[N], lst[N], vis[N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
rep(i, 1, n) cin >> a[i];
per(i, n, 1) {
if(a[i] < i) {
cout << 0 << endl;
return 0;
}
if(lst[a[i]]) vis[lst[a[i]]] = 1;
else if(i != a[i]) {
cout << 0 << endl;
return 0;
}
lst[a[i]] = i;
}
mint cnt = 0, ans = 1;
rep(i, 1, n) {
cnt += !vis[i];
if(i == a[i]) {
ans *= cnt;
--cnt;
}
}
cout << ans << endl;
return 0;
}