EXCRT
为了契合整个系统,定义 gcd(x,0)=x。
欧几里得算法
证明 gcd(a,b)=gcd(b,a mod b):
- gcd(a,b)|gcd(b,a mod b):
a mod b=a−kbgcd(a,b)|agcd(a,b)|b⇒gcd(a,b)|gcd(b,a mod b)
- gcd(b,a mod b)|gcd(a,b):
a mod b+kb=agcd(b,a mod b)|gcd(b,a mod b)gcd(b,a mod b)|b⇒gcd(b,a mod b)|gcd(a,b)
扩展欧几里得算法
扩展欧几里得算法解决的是这样的二元一次不定方程:ax+by=gcd(a,b)。
设
ax1+by1=gcd(a,b)bx2+(a mod b)y2=gcd(b,a mod b)
由辗转相除法:
ax1+by1=bx2+(a mod b)y2ax1+by1=bx2+(a−⌊ab⌋×b)y2ax1+by1=ay2+b(x2−⌊ab⌋y2)
递归求解 bx2+(a mod b)y2=gcd(b,a mod b)。这个递归显然是有边界的,即 b=0,此时 x=1,y=0 即是合法解。递归问题解决之后,当前问题的解就是 x1=y2,y1=x2−⌊ab⌋y2。
exgcd
exgcd解决的是这样的二元一次不定方程:ax+by=c。
首先由裴蜀定理:gcd(a,b)|c,否则无解。
根据上文,我们已经能解出ax0+by0=gcd(a,b)。
那么有:ax0cgcd(a,b)+by0cgcd(a,b)=c。这样我们就找到了一组特解。
接下来考虑通解:
a(x1+db)+b(y1−da)=c
因为 da,db 是整数,所以 d 一定是 1gcd(a,b) 的倍数。那么通解就是:
x=x1+bgcd(a,b)ky=y1−agcd(a,b)k
这也可以求指定范围解的个数。
CRT/EXCRT
算法流程:每次取出方程组中的两个方程,合并成一个。
如何合并:
{x≡r1(modm1)x≡r2(modm2)⇒a=k1m1+r1=k2m2+r2k1m1−k2m2=r2−r1
用exgcd解这个即可,合并后就是 x≡解(modlcm(m1,m2))。
本文作者:永无岛
本文链接:https://www.cnblogs.com/thedreammaker/p/17674996.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步