给你洗 n n n次牌,这副牌有m张牌,其中有一个大王,你每次会抽出最顶的一张然后看完之后就放回去,假设你看过x次大王,你的贡献就是x^k,求期望贡献
题目就是要求
= ∑ i = 1 n ( n i ) i k ( m − 1 ) n − i m n =\frac{\sum\limits_{i=1}^{n} \binom{n}{i} i^k(m-1)^{n-i}}{m^n} =mni=1∑n(in)ik(m−1)n−i
然后一看这种形式大多就用第二斯特林数展开
n k = ∑ i = 0 k S ( k , i ) i ! ( n i ) n^k = \sum\limits_{i=0}^{k}S(k,i)i!\binom{n}{i} nk=i=0∑kS(k,i)i!(in)
= ∑ i = 1 n ( n i ) ∑ j = 0 m i n ( i , k ) S ( k , j ) j ! ( i j ) ( m − 1 ) n − i m n =\frac{\sum\limits_{i=1}^{n}\binom{n}{i}\sum\limits_{j=0}^{min(i,k)}S(k,j)j!\binom{i}{j}(m-1)^{n-i}}{m^n} =mni=1∑n(in)j=0∑min(i,k)S(k,j)j!(ji)(m−1)n−i
= ∑ j = 0 m i n ( n , k ) S ( k , j ) ∑ i = j n n ! ( n − i ) ! ( i − j ) ! ( m − 1 ) n − i m n =\frac{\sum\limits_{j=0}^{min(n,k)}S(k,j)\sum\limits_{i=j}^{n} \frac{n!}{(n-i)!(i-j)!} (m-1)^{n-i}}{m^n} =mnj=0∑min(n,k)S(k,j)i=j∑n(n−i)!(i−j)!n!(m−1)n−i
考虑n很大,把后面带n的部分去掉
= ∑ j = 0 m i n ( n , k ) S ( k , j ) n ! ( n − j ) ! ∑ i = 0 n − j ( n − j i ) ( m − 1 ) n − i − j m n =\frac{\sum\limits_{j=0}^{min(n,k)}S(k,j)\frac{n!}{(n-j)!}\sum\limits_{i=0}^{n-j}\binom{n-j}{i}(m-1)^{n-i-j}}{m^n} =mnj=0∑min(n,k)S(k,j)(n−j)!n!i=0∑n−j(in−j)(m−1)n−i−j
用二项式定理合并之后就行了
= ∑ j = 0 m i n ( n , k ) S ( k , j ) n ! ( n − j ) ! m n − j m n =\frac{\sum\limits_{j=0}^{min(n,k)}S(k,j)\frac{n!}{(n-j)!}m^{n-j}}{m^n} =mnj=0∑min(n,k)S(k,j)(n−j)!n!mn−j
#include
#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;
}