Educational Codeforces Round 78 (Rated for Div. 2) F. Cards 第二類斯特林數

題意

給你洗nn次牌,這副牌有m張牌,其中有一個大王,你每次會抽出最頂的一張然後看完之後就放回去,假設你看過x次大王,你的貢獻就是x^k,求期望貢獻

分析

題目就是要求
=i=1n(ni)ik(m1)nimn=\frac{\sum\limits_{i=1}^{n} \binom{n}{i} i^k(m-1)^{n-i}}{m^n}
然後一看這種形式大多就用第二斯特林數展開
nk=i=0kS(k,i)i!(ni)n^k = \sum\limits_{i=0}^{k}S(k,i)i!\binom{n}{i}

=i=1n(ni)j=0min(i,k)S(k,j)j!(ij)(m1)nimn=\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}

=j=0min(n,k)S(k,j)i=jnn!(ni)!(ij)!(m1)nimn=\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}

考慮n很大,把後面帶n的部分去掉

=j=0min(n,k)S(k,j)n!(nj)!i=0nj(nji)(m1)nijmn=\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}

用二項式定理合並之後就行了

=j=0min(n,k)S(k,j)n!(nj)!mnjmn=\frac{\sum\limits_{j=0}^{min(n,k)}S(k,j)\frac{n!}{(n-j)!}m^{n-j}}{m^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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章