zoukankan      html  css  js  c++  java
  • P6620[省选联考2020A卷]组合数问题【组合数学,斯特林数】

    正题

    题目链接:https://www.luogu.com.cn/problem/P6620


    题目大意

    给出\(n,x,p,m\)和一个\(m\)次多项式\(f\)

    \[\sum_{k=0}^nf(k)\times x^k\times \binom{n}{k} \]

    答案对\(p\)取模。

    \(1\leq n\leq 10^9,1\leq m\leq 1000\)


    解题思路

    什么混凝土数学题

    首先我们发现这个组合数\(\binom{n}{k}\)处理的十分难受,有一个下降幂的结论正好可以把这个难受的\(k\)变掉。

    \[\binom{n}{k}\times k^{\underline{m}}=\binom{n-m}{k-m}\times n^{\underline m} \]

    我们需要找到一个东西来提供\(k^{\underline m}\),此时给我们的多项式\(f\)就是一个不错的选择。

    我们考虑把多项式转换为下降幂的形式

    \[f(x)=\sum_{i=0}^ma_ix^i=\sum_{i=0}^mb_ix^{\underline i} \]

    考虑一下怎么找到序列\(b_i\),也就是我们需要把\(x^i\)转换为下降幂的形式,有一个第二类斯特林数的性质就是

    \[x^n=\sum_{i=0}^{n}{\begin{Bmatrix}n\\i\end{Bmatrix}}x^{\underline i} \]

    \[\sum_{i=0}^ma_ix^i=\sum_{i=0}^ma_i\sum_{j=0}^i{\begin{Bmatrix}i\\j\end{Bmatrix}}x^{\underline j}\Rightarrow b_i=\sum_{i=j}^n{\begin{Bmatrix}j\\i\end{Bmatrix}}x^{\underline{i}} \]

    然后就可以继续推我们的式子了

    \[\sum_{k=0}^n\sum_{i=0}^mb_ik^{\underline i}\times x^k\times \binom{n}{k} \]

    \[\sum_{k=0}^n\sum_{i=0}^mb_ix^k\binom{n-i}{k-i}n^{\underline i} \]

    \(i\)提出去枚举

    \[\sum_{i=0}^mb_in^{\underline i}\sum_{k=0}^nx^k\binom{n-i}{k-i} \]

    \[\Rightarrow \sum_{i=0}^mb_in^{\underline i}x^i\sum_{k=0}^{n-i}\binom{n-i}{k}x^k \]

    然后后面那个式子就可以二项式定理了

    \[\Rightarrow \sum_{i=0}^mb_in^{\underline i}x^i(x+1)^{n-i} \]

    然后就搞定了

    时间复杂度\(O(m^2+m\log n)\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=1100;
    ll n,x,m,P,a[N],b[N],s[N][N],ans;
    ll power(ll x,ll b){
    	ll ans=1;
    	while(b){
    		if(b&1)ans=ans*x%P;
    		x=x*x%P;b>>=1;
    	}
    	return ans;
    }
    signed main()
    {
    	scanf("%lld%lld%lld%lld",&n,&x,&P,&m);
    	for(ll i=0;i<=m;i++)scanf("%lld",&a[i]);
    	s[0][0]=1; 
    	for(ll i=1;i<=m;i++)
    		for(ll j=1;j<=i;j++)
    			s[i][j]=(s[i-1][j]*j%P+s[i-1][j-1])%P;
    	for(ll i=0;i<=m;i++)
    		for(ll j=i;j<=m;j++)
    			(b[i]+=a[j]*s[j][i]%P)%=P;
    	for(ll i=0,tmp=1;i<=m;i++){
    		(ans+=b[i]*tmp%P*power(x,i)%P*power(x+1,n-i)%P)%=P;
    		tmp=tmp*(n-i)%P;
    	}
    	printf("%lld\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    个人永久性免费-Excel催化剂功能第86波-人工智能之图像OCR文本识别全覆盖
    git删除远程仓库的文件或目录
    使用document.execCommand复制内容至剪贴板
    使用clipboard.js实现复制内容至剪贴板
    正则匹配目标字符串不等于某些特定的字符串
    substr与substring的用法
    使用hexo搭建个人博客
    git修改最后一次commit的内容
    gulp压缩文件最简示例
    gulp最简示例
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14578690.html
Copyright © 2011-2022 走看看