[題解] LOJ 3300 洛谷 P6620 [省選聯考 2020 A 卷] 組合數問題 數學,第二類斯特林數,下降冪
阿新 • • 發佈:2022-05-08
題目
題目裡要求的是:
這裡面出現了給定的多項式,還有組合數,這種題目的套路就是先把給定的普通多項式轉成下降冪多項式。這一步可以做到\(O(mlogm)\),(模板)但是這題不需要,這個後面再說。假設現在已經得出了f的下降冪多項式的係數\(b_i\),則:
\[\begin{align} f(k)&=\sum_{i=0}^m b_ik^{\underline i}\\ ans&=\sum_{k=0}^n f(k) \times X^k \times \binom nk\\ &=\sum_{k=0}^n \sum_{i=0}^m b_i k^{\underline i} X^k\frac{n!}{(n-k)!k!}\\ &=\sum_{i=0}^m b_i \sum_{k=i}^n \frac{k!}{(k-i)!}\cdot \frac{n!}{(n-k)!k!}(交換求和符號,k從i開始因為k<i時下降冪的值為0)\\ &=\sum_{i=0}^m b_i \sum_{k=i}^n \frac{(n-i)!}{(k-i)!(n-k)!}\cdot X^{k-i}\cdot 1^{n-k}X^i\cdot n^{\underline i}\\ &=\sum_{i=0}^m b_i \sum_{k=i}^n \binom{n-i}{k-i}\cdot X^{k-i}\cdot 1^{n-k}X^i\cdot n^{\underline i}\\ &=\sum_{i=0}^m b_i (1+x)^{n-i}X_i\cdot n^{\underline i}(二項式定理,這種題的套路)\\ \end{align} \]\(k^{\underline i}\)
眾所周知 \(x^n=\sum_{i=0}^n S2(n,i) x^{\underline i}\)
所以
\[\begin{align} \sum_{i=0}^m a_i x^i&=\sum_{i=0}^m a_i \sum_{j=0}^i S2(i,j) x^{\underline j}\\ &=\sum_{i=0}^m x^{\underline i} \sum_{j=i}^m a_j S2(j,i)(交換求和符號)\\ \end{align} \]所以\(b_i=\sum_{j=i}^m a_j S2(j,i)\)
第二類斯特林數可以暴力\(O(m^2)\)遞推:\(S2(n,m)=S2(n-1,m-1)+m \cdot S2(n-1,m)\)。
總時間複雜度\(O(m^2)\)。
點選檢視程式碼
#include <bits/stdc++.h> #define rep(i,n) for(int i=0;i<n;++i) #define repn(i,n) for(int i=1;i<=n;++i) #define LL long long #define pii pair <LL,LL> #define fi first #define se second #define mpr make_pair #define pb push_back using namespace std; LL n,x,MOD,m,a[1010],b[1010],s2[1010][1010],ans=0; LL qpow(LL xx,LL a) { LL res=xx,ret=1; while(a>0) { if((a&1)==1) ret=ret*res%MOD; a>>=1; res=res*res%MOD; } return ret; } int main() { cin>>n>>x>>MOD>>m; rep(i,m+1) scanf("%lld",&a[i]); s2[0][0]=s2[1][1]=1; for(int i=2;i<=m+3;++i) repn(j,i) s2[i][j]=(s2[i-1][j-1]+s2[i-1][j]*(LL)j)%MOD; rep(i,m+1) for(int j=i;j<=m;++j) (b[i]+=a[j]*s2[j][i])%=MOD; LL mul=1; rep(i,m+1) { (ans+=b[i]*qpow(1+x,n-i)%MOD*qpow(x,i)%MOD*mul)%=MOD; (mul*=(n-i))%=MOD; } cout<<ans<<endl; return 0; }