H2ptimize
2024-11-16 23:56:08
让我们思考一下“无限轮”。
不难发现,根据 Aob 的行动方式,经过足够次随机后,最终集合
因此只需要考虑
对于一组满足
这样我们已经完成了性质 A,只需要统计对于每个
我们先将能填充的缺失部分填好。对于
当所有能填的空填完后,问题就转化为了性质 B。记排列
这个是问题相当于求数列 A000085,记 场上查到 oeis 之后把递推式打成了 dp[i]=dp[i-1]-(cnt-1)*dp[i-2]
怒挂 70 分,唐!
至此,此题得解。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e6+10,P=998244353;
int n,p[MAXN],dp[MAXN];
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>p[i];
for(int i=1;i<=n;i++)
{
if(p[i]&&!p[p[i]])p[p[i]]=i;
}
int cnt=0;
for(int i=1;i<=n;i++)
{
if(p[i]==0)cnt++;
else if(p[p[i]]==i)continue;
else
{
cout<<0;
return 0;
}
}
dp[0]=dp[1]=1;
for(int i=2;i<=cnt;i++)dp[i]=(dp[i-1]+dp[i-2]*(i-1))%P;
cout<<dp[cnt];
return 0;
}