Lucas 定理

Lucas 定理,一般用于求某组合数对某质数取模的值,即 (nm)modp

一般来说,这种东西有一堆求法。n,m 小的话可以直接递推,p>n 可以根据定义 (nm)=n!m!(nm)! 预处理阶乘和阶乘的逆元求。但是如果 pn,阁下又当如何应对?此时你不能保证 nnmp 的逆元存在。于是我们使用—— Lucas 定理。

Lucas 定理

(nm)i=0x(nimi)(modp),其中 ni,mi 分别为 n,mp 进制下的各位数字,即 n=i=0xnipim=i=0xmipi

这样我们就可以递归地在 logp 的时间复杂度内求出答案了。代码也很好写:

int CC(int n, int m) { return (n < m ? 0 : fac[n] * ifac[m] % P * ifac[n - m] % P); }
int C(int n, int m) { return (n == 0 ? 1 : C(n / P, m / P) * CC(n % P, m % P) % P); }

需要预处理 p 以内的阶乘及其逆元。这个肯定是存在的。

接下来我们尝试证明 Lucas 定理。

证明

引理 1

p 为质数且 1k<p,则 (pk)0(modp)

根据定义,(pk)=p!k!(pk)!=p(p1)(p2)(pk+1)k!。我们知道 (pk) 肯定是个整数,所以 k!|p(p1)(p2)(pk+1)。又因为 p 是个质数,而 k<p,所以 1k 中一定没有 p 的因子,所以 k! 一定与 p 互质。所以 k!|(p1)(p2)(pk+1),即 (p1)(p2)(pk+1)k! 肯定是个整数。发现没?这里少了个 p。那说明 p 肯定就是 (pk) 的一个因数,即 (pk)0(modp)

引理 2

p 为质数,则 (1+x)p1+xp(modp)

有了上一个引理的铺垫,这个证起来就很简单了。根据二项式定理,我们有 (1+x)p=i=0p(pi)xi。根据引理 1,我们有 (pi)0(modp)(1i<p),也就是当 1i<p 时,(pi)xi0(modp)。所以 (1+x)p(p0)x0+(pp)xp=1+xp(modp)

引理 3

p 为质数,则 (1+x)pi1+xpi(modp)

我们考虑将 pi 里面的 p 一个个地“搬”到括号里。即 (1+x)pi=((1+x)p)pi1(1+xp)pi1(modp)。然后将 xp 视为新的 x,再进行如上的操作,得到 (1+xp2)pi2,以此类推,直到括号外 p 变为 0 次为止。这样就可以得到 (1+x)pi1+xpi(modp)

接下来我们开始证明 Lucas 定理。

考虑一个式子 K=0N(NK)XK。我们接下来对它进行变形。

(1)K=0N(NK)XK=(1+X)NNP=(1+X)i=0xniPia(b+c)=ab·ac=i=0x(1+X)niPi=i=0x((1+X)Pi)ni使3=i=0x(1+XPi)niYi=XPi使=i=0x(j=0ni(nij)Yij)n<m(nm)=0niNPniP1P10=i=0x(j=0P1(nij)Yij)西(a1+a2+)(b1+b2+)西fi,j=(nij)Yij=(f0,0+f0,1++f0,P1)(f1,0+f1,1++f1,P1)(fx,0+fx,1++fx,P1)=f0,0f1,0fx,0+f0,0f1,0fx1,0fx,1++f0,P1f1,P1fx,P1A0P1=j0,j1,jxAi=0xfi,ji=j0,j1,jxAi=0x(niji)YijiXi=j0,j1,jxAi=0x(niji)(XPi)jiab=ab=j0,j1,jxAi=0x(niji)i=0xXjiPiab·ac=ab+c=j0,j1,jxAi=0x(niji)Xj=0xjiPiXPjiPj0jxxPjPKMxP=K=0Mi=0x(niji)XKNK>NnijiNKPi使ni<ji(niji)0K0K=K=0Ni=0x(niji)XK(modP)

对比最后一个式子和第一个式子,即 K=0N(NK)XKK=0Ni=0x(niji)XK(modP)。由于两边模 P 是等价的,所以相同次数的 X 应当拥有(在模 P 意义下)相同的系数。所以 (NK)i=0x(niji)(modP)。证毕。

posted @   forgotmyhandle  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示