Lucas定理——定义、证明、实现、运用
什么是Lucas定理
这是一个有助于分解组合数来求解的定理,适合模数小,数字大的问题。
有质数
由此可以分解成较小的问题求解。
证明Lucas定理
这个证明利用了二项式定理的思路,前所未闻,真的很有趣。
根据二项式定理可以得到
我们用这一点作为突破口,对于
然后有一个很有意思的东西
为什么呢?将式子拆开后,显然除了第一项与最后一项,其他项是
继续进行推导,我们有
于是右边的式子拆开可以得到
我们要求
由于
剩下部分由
因此
由此,完成了Lucas定理的证明。
Lucas定理求解组合数的C++实现
代码上没什么难点,首先基础的组合数求解还是要有的,也就是我们需要预处理阶乘逆元,然后使用Lucas将组合数拆开再用基础的组合数求解即可。
long long ksm(long long x,long long y) { long long sum=1; while(y) { if(y&1) { sum*=x; sum%=mod; } x*=x; x%=mod; y>>=1; } return sum; } long long C(long long n,long long m) { if(m>n)return 0; if(m==0||n==m)return 1; return fac[n]*inv[m]%mod*inv[n-m]%mod; } long long lucas(long long n,long long m) { if(m>n)return 0; if(n<mod)return C(n,m); return lucas(n/mod,m/mod)*lucas(n%mod,m%mod)%mod; } void init() { fac[0]=1; for(int i=1;i<=mod-1;i++) { fac[i]=fac[i-1]*i%mod; } inv[mod-1]=ksm(fac[mod-1],mod-2); for(int i=mod-2;i>=0;i--) { inv[i]=inv[i+1]*(i+1)%mod; } }
如果觉得不错的话,就给一个赞吧!
作者是 DengDuck ,转载请注明出处
文章链接: https://www.cnblogs.com/dengduck/p/17353463.html
感谢您阅读!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步