lucas定理
Update:
代码已更新,之前的代码算数时会溢出 QAQ
应用:
Lucas定理的应用范围在于大的组合数取模。简而言之,就是用来求 c(n,m) mod p,p为素数的值。
定义:
C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
求解上式时,递归出口为 m = 0 时返回 1.
证明:
下面附上Lucas定理的一种证明,见下图,参考冯志刚《初等数论》第37页。
对于证明过程的一些解释:
update:上面第三条的C(a,b)应该是C(b,a)。
代码实现:
typedef long long LL; const LL mod = 1e9+7; LL quick_pow(LL x, LL n, LL p)// 快速幂求x^n mod p 的结果 { if(n==0) return 1; if(n==1) return x%p; LL ans = 1; LL tmp = x%p; while(n) { if(n&1) { ans = (ans*tmp)%p; } tmp = tmp*tmp%p; n>>=1; } return ans%p; } LL inv(LL b,LL p) //求数 b mod p 的逆元 { return quick_pow(b,p-2,p); } LL C(LL n,LL m,LL p)//组合数取模 { if(m==0|| m== n) return 1; if(m==1||m==n-1) return n%p; m = min(m,n-m); LL up = 1,down = 1; for(LL i = n-m+1;i<=n;i++) up=(up*i)%p; for(LL i = 1;i<=m;i++) down=(down*i)%p; up%=p; down%=p; return (up*(inv(down,p)%p))%p; } LL lucas(LL n,LL m,LL p)//递归lucas函数 { if(m==0) return 1; return lucas(n/p,m/p,p)*C(n%p,m%p,p)%p; }
如果对求逆元不是十分了解,欢迎去我的上一篇博客去看看。
如果还有疑问,欢迎在评论区留言/
过往不恋 未来不迎 当下不负
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】