【題解】Atcoder Beginner Contest226 F - Score of Permutations

F - Score of Permutations

\(\text{Soluton:}\)

首先看清題意,對於每一個置換環,球會不斷輪換,直到停止。而停止輪數自然也就是所有環長的 \(\text{lcm}\) 了。

那麼考慮對一個 \(\text{lcm}\) 算貢獻。有一個顯然的 \(dp:\)

\[f[i+j][\text{lcm}\{j,k\}]=\sum f[i][k]\times \binom{n-1-i}{j-1}\times (j-1)! \]

解釋含義:設 \(f[i][j]\) 表示用 \(i\) 個點拼成所有環長的 \(\text{lcm}=j\) 的置換個數。那麼考慮枚舉一個長度爲 \(k\) 的環貼上去:

那麼我們發現,首先我們需要從剩下的點裏面選出 \(k\) 個點,組成一個環。

那實際就是求了一個在剩下 \(n-i\) 個點的環排列個數,也就是 \(\binom{n-i-1}{x-1}\times (x-1)!\)

#include<bits/stdc++.h>
using namespace std;
typedef double db;
#define int long long
const int mod=998244353;
const db eps=1e-14;
inline int Max(int x,int y){return x>y?x:y;}
inline int Min(int x,int y){return x<y?x:y;}
inline db Max(db x,db y){return x-y>eps?x:y;}
inline db Min(db x,db y){return x-y<eps?x:y;}
inline int Add(int x,int y,int M=mod){return (x+y)%M;}
inline int Mul(int x,int y,int M=mod){return 1ll*x*y%M;}
inline int Dec(int x,int y,int M=mod){return (x-y+M)%M;}
inline int Abs(int x){return x<0?-x:x;}
inline int read(){
	int s=0,w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
	while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}
	return s*w;
}
inline void write(int x){
	if(x<0)putchar('-'),x=-x;
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
inline int qpow(int x,int y){
	int res=1;
	while(y){
		if(y&1)res=Mul(res,x);
		x=Mul(x,x);y>>=1;
	}
	return res;
}
typedef pair<int,int> pr;
#define fi first
#define se second
#define mk make_pair
#define pb emplace_back
#define poly vector<int>
const int N=2e5+10;
inline void cadd(int &x,int y){x=Add(x,y);}
namespace Refined_heart{
	int fac[N],inv[N],n,K;
	inline int C(int x,int y){return Mul(fac[x],Mul(inv[y],inv[x-y]));}
	inline int gcd(int x,int y){return !y?x:gcd(y,x%y);}
	inline int lcm(int x,int y){return x*y/gcd(x,y);}
	map<int,int>f[501];
	void solve(){
		n=read(),K=read();
		fac[0]=1;
		for(int i=1;i<=5001;++i)fac[i]=Mul(fac[i-1],i);
		inv[5001]=qpow(fac[5001],mod-2);
		for(int i=5001;i;--i)inv[i-1]=Mul(inv[i],i);
		f[0][1]=1;
		for(int i=0;i<n;++i){
			for(auto &[key,val]:f[i]){
				for(int j=1;j+i<=n;++j){
					cadd(f[i+j][lcm(key,j)],Mul(val,Mul(fac[j-1],C(n-i-1,j-1))));
				}
			}
		}
		int ans=0;
		for(auto &[key,val]:f[n])cadd(ans,Mul(val,qpow(key,K)));
		printf("%lld\n",ans);
	}
}
signed main(){
	Refined_heart::solve();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章