【CF932E】Team Work(第二類斯特林數)

【CF932E】Team Work(第二類斯特林數)

題面

洛谷
CF
\(\sum_{i=1}^nC_{n}^i*i^k\)ios

題解

寒假的時候被帶飛,這題被帶着寫了一遍。事實上並不難,咱們來頹柿子。
首先回憶一下第二類斯特林數關於整數冪的計算公式:
\[m^n=\sum_{i=0}^mC_{m}^i*S(n,i)*i!\]
\(m^n\)理解爲把\(n\)個不一樣的球放到\(m\)個不一樣的盒子中去。那麼咱們枚舉有幾個盒子非空,用第二類斯特林數乘階乘計算放置的方案數,最後求和就是結果。
那麼直接把\(i^k\)展開
\[\sum_{i=1}^nC_n^i\sum_{j=0}^iC_i^j*S(k,j)*j!\]
把組合數直接拆開
\[\sum_{i=1}^n\frac{n!}{i!(n-i)!}\sum_{j=0}^i\frac{i!}{j!(i-j)!}*S(k,j)*j!\]
化簡以後的結果就很好看了。
\[\sum_{i=1}^n\frac{n!}{(n-i)!}\sum_{j=0}^i\frac{S(k,j)}{(i-j)!}\]
\(n\)的範圍太大,而\(k\)的範圍很小,因此考慮把斯特林數提出來放到外層循環
\[\sum_{j=0}^nS(k,j)\sum_{i=j}^n\frac{n!}{(n-i)!}*\frac{1}{(i-j)!}\]
由於第二類斯特林數\(S(k,j)\)若是\(j>k\)那麼結果就是\(0\),因此能夠不須要考慮。那麼式子能夠化簡\[\sum_{j=0}^{min(n,k)}S(k,j)\sum_{i=j}^n\frac{n!}{(n-i)!}*\frac{1}{(i-j)!}\]
後面的階乘孤零零的,給他配點東西就好看了。
\[\sum_{j=0}^{k}S(k,j)\sum_{i=0}^n\frac{n!}{(n-j)!}\frac{(n-j)!}{(n-i)!(i-j)!}\]
\[\sum_{j=0}^{k}S(k,j)\frac{n!}{(n-j)!}\sum_{i=0}^nC_{n-j}^{i-j}\]
\[\sum_{j=0}^{k}S(k,j)\frac{n!}{(n-j)!}2^{n-j}\]
由於\(k\)只有\(5000\),因此\(i\)的起始位置最多隻有\(5000\)個,那麼直接\(O(k)\)考慮計算便可。
斯特林數暴力\(O(k^2)\)預處理,總的複雜度\(O(k^2)\)spa

#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 1000000007
#define inv2 500000004
#define MAX 5050
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int n,k,S[MAX][MAX],ans;
int main()
{
    scanf("%d%d",&n,&k);S[0][0]=1;
    for(int i=1;i<=k;++i)
        for(int j=1;j<=k;++j)
            S[i][j]=(S[i-1][j-1]+1ll*S[i-1][j]*j)%MOD;
    for(int j=0,pw=fpow(2,n),nw=1;j<=min(n,k);pw=1ll*pw*inv2%MOD,nw=1ll*nw*(n-j)%MOD,++j)
        ans=(ans+1ll*S[k][j]*nw%MOD*pw%MOD)%MOD;
    printf("%d\n",ans);
    return 0;
}
相關文章
相關標籤/搜索