_3Zinc_
2024-11-18 08:04:03
引流。
本人数学不好,语言可能不严谨,望大佬指出 QwQ
这道题看起来很复杂,但其实是诈骗题。
首先不难发现
为什么呢?我们不妨用反证法进行证明:
如果一个逆序对
根据题目中“无限轮”后平局的定义,当逆序对数为
所以能够使 Aob 和 Blice “无限轮”后平局,
知道这个后,我们就可以开始考虑代码实现了。
首先显然可以记录下每个数
统计剩下有多少个数能填时要注意分类和细节:
若
若
若
接下来看如何计算答案。假设还能填的数有
判断无解是
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
const ll mod=998244353;
const ll inv=499122177;
int n,a[N],r[N];
ll f[N];
int main() {
scanf("%d",&n);
int cnt=n;
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]);
if(!a[i]) continue ;
r[a[i]]=i;
}
for(int i=1;i<=n;i++) {
if(r[i]&&(r[i]!=a[i]&&a[i])) return printf("0\n"),0;
else if(r[i]) cnt--;
else if(r[a[i]]) cnt--;
}
f[0]=f[1]=1LL;
for(int i=2;i<=cnt;i++) {
ll x=i;
f[i]=(f[i-1]+f[i-2]*(x-1LL)%mod)%mod;
}
printf("%lld\n",f[cnt]);
return 0;
}