Processing math: 100%

『扩展欧几里得算法 Extended Euclid』

Parsnip·2018-12-13 19:38·2483 次阅读

『扩展欧几里得算法 Extended Euclid』

<更新提示>

<第一次更新>


<正文>

Euclid算法(gcd)#

在学习扩展欧几里得算法之前,当然要复习一下欧几里得算法啦。
众所周知,欧几里得算法又称gcd算法,辗转相除法,可以在O(log2b)时间内求解(a,b)(a,b的最大公约数)。
其核心内容可以陈述为:(a,b)=(b,a%b),然后反复迭代该式缩小a,b规模,直到b=0,得到a为最大公约数。

证明#

设两数为a b(b<a),求它们最大公约数的步骤如下:用ba,即a/b=q..r,得abqr(0r<b),即为余数,q是这个除法的商)。若r=0,则bab的最大公约数,ab存在倍数关系。若r0,则继续考虑。

首先,应该明白的一点是任何 ab 的公约数都是 r 的公约数。要想证明这一点,就要考虑把 r 写成 r=abq。现在,如果 ab 有一个公约数 d,而且设 a=sd,b=td, 那么 r=sdtdq=(stq)d。因为这个式子中,所有的数(包括 stq)都为整数,所以 r 可以被 d 整除。

对于所有的 d 的值,这都是正确的。所以 ab 的最大公约数也是 b(因为b<a,所有取b继续运算才能不断缩小规模,直至两数有倍数关系) 和 r 的最大公约数。因此我们可以继续对 br 进行上述取余的运算。这个过程在有限的重复后,可以最终得到 r=0 的结果,我们也就得到了 ab 的最大公约数

实现#

Code:

Copy
inline int Euclid(int a,int b){return b==0?a:Eucild(b,a%b);}

Extended Euclid算法(exgcd)#

那么接下来就是扩展欧几里得啦。
正如其名,扩展欧几里得算法就是基于欧几里得算法的扩展运用。该算法用于解决一下模型的问题:

求解关于x,y的二元不定方程ax+by=c的整数解

在讲解算法之前,需要先了解该算法的核心,即裴蜀定理:

对任何整数a,b,关于未知数x和y的线性丢番图方程(称为裴蜀等式):ax+by=c,方程有整数解当且仅当c(a,b)的倍数。裴蜀等式有解时必然有无穷多个解。

证明#

1.必要性证明:如果有整数解,则cp的倍数
p=(a,b),设a=apb=bp,则有(a,b)=1成立。那么

ax+by=capx+bpy=cp(ax+by)=c

那么c就是p的一个因数,所以p|c得证。

2.充分性证明:如果cp的倍数,则ax+by=c有整数解
p=(a,b),记欧几里得算法中每一次辗转得到的数对为(a1,b1),(a2,b2),...,(an,bn),其中,(a1,b1)即为(a,b)(an,bn)即为(p,0),符合辗转相除法的流程。
对于(an,bn),求方程anx+bny=c的解,由于an=p,bn=0,我们可以构造一组解:

{xn=cpynZ

适用于(an,bn),且(xn,yn)一定为整数(因为p|cyn取任意整数)。

至此,数学归纳法的底基证明完毕。

由于辗转相除法,我们可以得知

an=bn1 bn=an1%bn1bn=an1an1/bn1bn1 

我们刚才已经推得:anx+bny=c的一组整数解(xn,yn),那么可以把两式代入anx+bny=c得:

(bn1)x+(an1an1/bn1bn1)y=c

且对于该方程,解(xn,yn)仍适用,即:

(bn1)xn+(an1an1/bn1bn1)yn=c

成立,可以进行推导:

(bn1)xn+(an1an1/bn1bn1)yn=cbn1xn+an1ynan1/bn1bn1yn=can1yn+bn1(xnan1/bn1yn)=c 

注意到两项的系数分别为an1,bn1,所以对于方程an1x+bn1y=c,通过③式可以直接得到一组解:

{xn1=ynyn1=xnan1/bn1yn

由此,我们利用辗转相除法的关系,通过方程anx+bny=c的一组解(xn,yn),推得了方程an1x+bn1y=c的一组解(xn1,yn1)
同样地,我们可以由(xi,yi)的一组解,得到方程ai1x+bi1y=c的一组解(xi1,yi1)

{xi1=yiyi1=xiai1/bi1yi

由上,数学归纳法完成证明:如果我们得知anx+bny=c的一组解(xn,yn),且(a1,b1),(a2,b2),...,(an,bn)是由辗转相除法得到的序列,那么我们就可以通过以上方法得到原方程a1x+b1y=c的解(x1,y1)

然而,我们已经通过构造法得到anx+bny=c的一组解(xn,yn),且保证c是p的倍数时,整数解(xn,yn)一定存在。故c是p的倍数时,方程ax+by=c一定有整数解。充分性得证。

实现#

回归正题,看扩展欧几里得算法。
千万不要想着不看证明咯。裴蜀定理的充分性证明过程就是扩展欧几里得算法的流程。
先由辗转相除法求解(a,b),得到p=(a,b)
同时,构造解(xn,yn)

{xn=cpynZ

在递归的回溯过程中,利用公式:

{xi1=yiyi1=xiai1/bi1yi

倒推每一组(ai,bi)的解(xi,yi)
最后得到(a,b)和原方程ax+by=c的一组解(x,y)
至此,扩展欧几里得算法完成。

Code:

Copy
#include<bits/stdc++.h> using namespace std; inline int Extended_Euclid(int a,int &x,int b,int &y,int c) { if(b==0){x=c/a,y=0;return a;} else { int p=Extended_Euclid(b,x,a%b,y,c); int x_=x,y_=y; x=y_; y=x_-a/b*y_; return p; } } int main(void) { int a,b,c; scanf("%d%d%d",&a,&b,&c); int p,x,y; p=Extended_Euclid(a,x,b,y,c); printf("(%d,%d)=%d\n",a,b,p); printf("x=%d,y=%d\n",x,y); }

<后记>

posted @   Parsnip  阅读(2483)  评论(0)    收藏  举报
编辑推荐:
· 长文讲解 MCP 和案例实战
· Hangfire Redis 实现秒级定时任务,使用 CQRS 实现动态执行代码
· Android编译时动态插入代码原理与实践
· 解锁.NET 9性能优化黑科技:从内存管理到Web性能的最全指南
· 通过一个DEMO理解MCP(模型上下文协议)的生命周期
阅读排行:
· 工良出品 | 长文讲解 MCP 和案例实战
· 多年后再做Web开发,AI帮大忙
· centos停服,迁移centos7.3系统到新搭建的openEuler
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 上周热点回顾(4.14-4.20)
点击右上角即可分享
微信分享提示
目录