Wannafly Winter Camp 2020 Day 6J K重排列 - dp

时间:2023-03-09 15:20:16
Wannafly Winter Camp 2020 Day 6J K重排列 - dp

求 \(K\) 是多少个 \(n\) 元置换的周期。\(T\leq 100, n\leq 50, K \leq 10^{18}\)

Solution

置换可以被试做若干个环组成的有向图,于是考虑 dp,设 \(f[i]\) 表示 \(n=i\) 时的答案,则

\[f[i]=\sum_{j=1}^n [j|K] \cdot C_{i-1}^{j-1} \cdot (j-1)!\cdot f[i-j]
\]
#include <bits/stdc++.h>
using namespace std; #define int long long const int mod = 998244353;
const int N = 105;
int t,n,k,f[N],c[N][N],frac[N]; signed main() {
frac[0]=1;
for(int i=1;i<=100;i++) frac[i]=(frac[i-1]*i)%mod;
for(int i=0;i<=100;i++) c[i][0]=1;
for(int i=1;i<=100;i++) {
for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}
cin>>t;
while(t--) {
cin>>n>>k;
memset(f,0,sizeof f);
f[0]=1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
if(k%j==0) {
f[i]+=c[i-1][j-1]*frac[j-1]%mod*f[i-j]%mod;
f[i]%=mod;
}
}
}
cout<<f[n]<<endl;
}
}