題意
給你洗次牌,這副牌有m張牌,其中有一個大王,你每次會抽出最頂的一張然後看完之後就放回去,假設你看過x次大王,你的貢獻就是x^k,求期望貢獻
分析
題目就是要求
然後一看這種形式大多就用第二斯特林數展開
考慮n很大,把後面帶n的部分去掉
用二項式定理合並之後就行了
代碼
#include <bits/stdc++.h>
#define pb push_back
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
const ll N = 1000010;
const ll inf = 1e9;
const ll mod = 998244353;
inline ll read()
{
ll p=0; ll f=1; char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
return p*f;
}
ll qpow(ll x,ll k,ll mo)
{
ll s = 1;
while(k)
{
if(k&1) s=s*x%mo;
x=x*x%mo; k>>=1;
}return s;
}
ll n,m,k,S[5010][5010];
int main()
{
n = read(); m = read(); k = read();
S[0][0] = 1; S[1][0] = 0;
for(ll i=1;i<=k;i++) for(ll j=0;j<=k;j++)
{
if(j==0) S[i][j] = 0;
else S[i][j] = (S[i-1][j-1] + S[i-1][j] * j % mod) % mod;
// printf("%lld %lld : %lld\n",i,j,S[i][j]);
}
ll s=1; ll ans = 0; ll mb = qpow(m,n,mod); ll invm = qpow(m,mod-2,mod); // printf("%lld\n",invm);
for(ll j=0;j<=min(n,k);j++)
{
ans = (ans + S[k][j] * s % mod * mb % mod) % mod;
mb = mb * invm % mod,s = s * (n-j) % mod;
// if(ans < 0) printf("%lld\n",j);
}// printf("%lld\n",ans);
return printf("%lld\n",ans * qpow(qpow(m,n,mod),mod-2,mod) % mod),0;
}