求阶乘逆元

// 求阶乘逆元
//考虑 (a/b)%mod 其中a和b都是很大的数 在得到a和b前都要%mod
//如果直接除,会丢失精度 

//解决办法:转化成 a*(b在模mod状态下的逆元) (这样a/b <=> a*b的逆元)  
//由费马小定理:a^(p-1)=1(mod p)   //p为素数 
//可知a在模p下的的逆元是a^(p-2) 
#include<cstdio>
#define ll long long
using namespace std;
const int N = 1000001;
const int mod = 998244353;
int n,m,k;
ll fac[N],inv[N];  //阶乘,逆元 

ll quickpow(ll a,ll x){  //底数也开ll  因为可能是inv[] 
	ll ans=1;
	while(x){
		if(x&1){
			ans*=a;	
			ans%=mod;
		}
		a*=a;
		a%=mod;
		x/=2;
	}
	return ans;
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	fac[0]=1;
	for(int i=1;i<=n;i++){
		fac[i]=fac[i-1]*i%mod;
	}
	inv[n]=quickpow(fac[n],mod-2);  //n的逆元   即1/(n+1)! (mod p) 
	for(int i=n-1;i>=1;i--){
		inv[i]=inv[i+1]*(i+1)%mod;  // 1/n!=1/(n+1)! * (n+1) %p
	}
	printf("%lld",(fac[k]*quickpow(inv[k/m],m))%mod);  
	//求 k!/(k/m)!^m 
	//转化成 求 k!*(m/k)^m  (mod p)
	return 0;
} 
posted @ 2021-03-28 13:15  starlightlmy  阅读(440)  评论(0)    收藏  举报