题意
给你洗 次牌,这副牌有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;
}