Exgcd(扩展欧几里得算法)

其实挺简单。

GCD(辗转相除法)

定理:

gcd(a,b)=gcd(b,amodb)

证明:

设 a=kb+r ,则 r=amodb

若 c 是 a,b 的一个公约数,则 ca,cb

r=akb

cr

c 是 b,amodb 的公约数

同理,若 d 是 b,amodb 的公约数,则 db,dr

a=kb+r

da

d 也是 a,b 的公约数

a,b 和 b,amodb 的公约数是一样的,其最大公约数也必然相等,证毕

code(递归式):

int gcd(int a,int b){
return (b==0)?a:gcd(b,a%b);
}

EXGCD(扩展欧几里得)

裴蜀定理:

a,bZ , x,yZ

满足

ax+by=gcd(x,y)

证明(考虑数学归纳):

b=0 时:

gcd(a,b)=a ,此时 x=1,y=0

b0 时:

设 ax1+by1=gcd(a,b)=gcd(b,amodb)=bx2+(amodb)y2

amodb=aa/bb

ax1+by1=bx2+(aa/bb)y2

ax1+by1=bx2+ay2a/bby2

ax1+by1=ay2+bx2ba/by2

ax1+by1=ay2+b(x2a/by2)

解得 x1=y2,y1=x2a/by2

得证
通过这个证明,我们发现可以在维护 gcd 时同时维护 x,y 的值。

code:

int exgcd(int a,int b,int &x,int &y){
if(b==0) {x=1,y=0;return a;}
else{
int ans=exgcd(b,a%b,y,x);
y-=a/b*x;
return ans;
}
}

用途(1,2为基本用途):

1.

首先看怎么解

ax+by=c

这类方程

首先:若 gcd(a,b)c 可以知道原方程没有整数解(等式左右因数不相等,显然无整数解。
所以我们将原方程左边 ×gcd(a,b)/c ,然后通过解 ax0+by0=gcd(a,b) 解得 x0,y0 ,最后将 x0,y0 乘上 c/gcd(a,b) 解出原方程的一组解 x1,y1.
显然,我们将 x1+b/gcd(a,b)t,y1a/gcd(a,b)tt 为任意整数)即可得出所有解。

2.

然后,我们再来看下同余方程

axl(modm)

其实稍加转化,就得到了

ax+my=l

解这个方程即可,注意 x 的特殊要求。

3.

最后,我们来看一下同余方程组

{xa1(modm1)xa2(modm2)...xan(modmn)

若所有 m 互质,可以用 crt 求解。
这里主要说不互质的用 exgcd 解法
首先看第一二个式子:

{xa1(modm1)xa2(modm2)

变形得到:

{x=a1+m1k1x=a2+m2k2

a1+m1k1=a2+m2k2

整理:

m1k1m2k2=a2a1

运用 exgcd 解得 k1 的一组解:

k1=r

k1 的通解为 k1=r+m2gcd(m1,m2)×ttZ

将上式带入 x=a1+m1k1 得:

x=a1+m1r+m1m2gcd(m1,m2)×t

lcm(m1,m2)=m1m2gcd(m1,m2)

x=a1+m1r+lcm(m1,m2)×t

变形得到:

xa1+m1r(modlcm(m1,m2))

于是我们就成功将两个同余方程化简成了一个。
同理化简下去直到一个,求解即可。
例题

——后来 jijidawang 说这就是 excrt

posted @   5k_sync_closer  阅读(135)  评论(1编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示