Lucas 定理
Cnm≡Cnmodpmmodp⋅C⌊np⌋⌊mp⌋(modp)
证明
规定:invx 表示 x 在模 p 意义下的逆元
定理 1
Cxp≡p×invx×Cx−1p−1≡0(modp)(0<x<p)
证明:
Cxp=p!x!(p−x)!=p⋅(p−1)!x⋅(x−1)!(p−x)!=px⋅(p−1)!(x−1)![(p−1)−(x−1)]!=px⋅Cx−1p−1≡p⋅invx⋅Cx−1p−1(modp)
定理 2
(1+x)p≡1+xp(modp)
根据二项式定理:
(1+x)p=p∑i=0Cip⋅xi⋅1p−i=p∑i=0Cip⋅xi∵Cxp≡p⋅invx⋅Cx−1p−1≡0(modp)(0<x<p)∴(1+x)p=C0p⋅x0+Cpp⋅xp=1+xp
推 式 子
设 {s=⌊mp⌋r=mmodp,则 m=sp+r
∵(1+x)m=m∑k=0Ckmxk∴(1+x)m=(1+x)sp+r=(1+x)sp⋅(1+x)r=[(1+x)p]s⋅(1+x)r≡(1+xp)s⋅(1+x)r(modp)=s∑i=0Cisxip⋅r∑j=0Cjrxj=s∑i=0r∑j=0CisCjrxip+j
因为 ip+j 刚好会枚举到 [0,m] 中的整数各一次(对于每个在 [0,m] 中的整数 x 都可以拆成 ⌊xp⌋⋅p+xmodp 的形式,而 i=⌊xp⌋,j=xmodp),所以转而枚举 k=ip+j:
(1+x)m≡m∑k=0C⌊kp⌋sCkmodpr(modp)
令 k=n,则
Cnm≡C⌊np⌋s⋅Cnmodpr=Cnmodpmmodp⋅C⌊np⌋⌊mp⌋(modp)
得证.
代码实现
例题:洛谷 P3807 【模板】卢卡斯定理
如果寻求高效率,建议先预处理出 0~p 在模 p 意义下的逆元和 0~p 的阶乘:
for(int i=2;i<=p;i++)
{
fac[i]=1ll*fac[i-1]*i%p;
inv[i]=1ll*(p-p/i)*inv[p%i]%p;
}
然后再处理出 0~p 的阶乘的逆元:
for(int i=2;i<=p;i++)
inv[i]=1ll*inv[i-1]*inv[i]%p;
然后就是快快乐乐的 Lucas 了:
int C(int _m,int _n,int mod)
{
if(_n>_m) return 0;
return 1ll*fac[_m]*inv[_n]%mod*inv[_m-_n]%mod;
}
int Lucas(int _m,int _n,int mod)
{
if(_n==0){return 1;}
else return 1ll*C(_m%mod,_n%mod,mod)*Lucas(_m/mod,_n/mod,mod)%mod;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现