LOJ#3300. 「联合省选 2020 A」组合数问题 第二类斯特林数

考场上忘了第二类斯特林数公式,过于智障,这里再重新推一遍.  

首先,$S(i,j)$ 表示的意义是将 $i$ 个不同的球放入 $j$ 个相同的盒子中的方案数,且盒子不能为空.    

那么有 $S(i,j)=S(i-1,j-1)+S(i-1,j) \times j$ 分别表示新开一个盒子/放入之前的盒子.         

然后很多题会有 $\sum i^x$ 这种式子,这里 $i$ 的枚举范围很大,但是 $x$ 不大,所以用第二类斯特林数转化为 $O(x)$ 的做法
$\Rightarrow n^m=\sum_{i=0}^{min(n,m)} \binom{n}{i} i! S(m,i)$.    

 组合意义是 $n^m$ 表示将 $m$ 个不同的球放入 $n$ 个不同盒子的方案数,那么我们就枚举哪些盒子里装了球.      

原题:求$\sum_{k=0}^{n} f(k) x^k \binom{n}{k}$.   

其中 $f(x)$ 是一个 $m \leqslant 10^3$ 的多项式.   

考虑枚举 $f(x)$ 中每一个系数的贡献,有 $\sum_{i=0}^{m} a_{i} \sum_{k=0}^{n} k^i x^k \binom{n}{k}$ 

这里 $k$ 很大,$i$ 很小,所以考虑将 $k^i$ 转化,得到 

$\sum_{i=0}^{m} a_{i} \sum_{j=0}^{i} S(i,j) j! \sum_{k=j}^{n} \binom{k}{j} x^k \binom{n}{k}$  

后面那个组合数可以拆出来一个 $\binom{n}{j}$ 然后用二项式定理逆战开就得到 

$\sum_{i=0}^{m} a_{i} \sum_{j=0}^{i} S(i,j) n^{ \underline{j}}x^j (x+1)^{n-j}$. 

提前预处理阶乘和下降幂,时间复杂度为 $O(m^2)$.  

code:  

#include <cstdio>  
#include <cstring>
#include <algorithm>   
#define N 2004
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin)
using namespace std; 
int n,x,mod,m;    
int a[N],S[N][N],lw[N],pw[N],xi[N];     
int qpow(int xr,int y) {     
    int tmp=1;  
    for(;y;y>>=1,xr=(ll)xr*xr%mod)   
        if(y&1) tmp=(ll)tmp*xr%mod;   
    return tmp;    
}    
void init() { 
    S[0][0]=1;   
    for(int i=1;i<N;++i) {  
        for(int j=1;j<=i;++j) { 
            S[i][j]=(ll)(S[i-1][j-1]+(ll)S[i-1][j]*j%mod)%mod;  
        }
    }        
}
int main() {  
    //setIO("input");  
    scanf("%d%d%d%d",&n,&x,&mod,&m);    
    init();   
    for(int i=0;i<=m;++i) { 
        scanf("%d",&a[i]); 
    }
    pw[0]=lw[0]=1;   
    for(int i=1;i<=m;++i) {
        lw[i]=(ll)lw[i-1]*(n-i+1)%mod;   
        pw[i]=(ll)pw[i-1]*x%mod;
        xi[i]=(ll)qpow((x+1)%mod,n-i);          
    }   
    xi[0]=qpow((x+1)%mod,n);    
    int ans=0;  
    for(int i=0;i<=m;++i) {    
        int tmp=0;   
        for(int j=0;j<=i;++j) { 
            (tmp+=(ll)S[i][j]*lw[j]%mod*pw[j]%mod*xi[j]%mod)%=mod;  
        } 
        (ans+=(ll)tmp*a[i]%mod)%=mod;  
    } 
    printf("%d\n",ans);  
    return 0; 
}

  

posted @ 2020-07-21 07:41  EM-LGH  阅读(162)  评论(0编辑  收藏  举报