欧几里得算法&&扩展欧几里得算法(基础)

本文介绍了基础的欧几里得算法及其扩展版本,详细讲解了扩展欧几里得算法如何求解特定的二元线性方程,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近数论讲的比较多,蒟蒻表示完全懵逼。。。
本来想写篇莫比乌斯反演的,但是懒得搞那么多公式,所以挑篇简单的欧几里得来写,不过类欧几里得算法也是很难的(凉凉。。)所以降低一点难度,写篇基础的。
正题:
注:#define long long LL

欧几里得算法:

很简单的东西,等于辗转相除法,非常简单,贴个代码:

LL gcd(LL a,LL b)
{
    return b?gcd(b,a%b):a;
}

扩展欧几里得算法:

是用来解下面的二元方程的:
ax+by=gcd(a,b)ax+by=\mathrm{gcd(a,b)}ax+by=gcd(a,b)

首先我们需要知道两个式子:
a=a  mod  b+⌊ab⌋∗ba=a\;mod\;b+\lfloor\frac{a}{b}\rfloor*ba=amodb+bab
gcd(a,b)=gcd(b,a  mod  b)\mathrm{gcd(a,b)}=\mathrm{gcd(b,a\;mod\;b)}gcd(a,b)=gcd(b,amodb)

上面两个式子显然是对的,就不给证明了。
代入原式可得:
x∗(a  mod  b+⌊ab⌋∗b)+by=gcd(b,a  mod  b)x*(a\;mod\;b+\lfloor\frac{a}{b}\rfloor*b)+by=\mathrm{gcd(b,a\;mod\;b)}x(amodb+bab)+by=gcd(b,amodb)

展开括号,提公因式b
(a  mod  b)x+b(⌊ab⌋x+y)=gcd(b,a  mod  b)(a\;mod\;b)x+b(\lfloor\frac{a}{b}\rfloor x +y)=\mathrm{gcd(b,a\;mod\;b)}(amodb)x+b(bax+y)=gcd(b,amodb)

对照一下这个式子和原式:
a            x        +b            y  =gcd(a,          b)a\;\;\;\;\;\;x\qquad\;\;\;\;+\qquad b\;\;\;\;\;\; y\;=\mathrm{gcd(a,\;\;\;\;\;b)}ax+by=gcd(a,b)
b(⌊ab⌋x+y)+(a  mod  b)x=gcd(b,a  mod  b)b(\lfloor\frac{a}{b}\rfloor x +y)+(a\;mod\;b)x=\mathrm{gcd(b,a\;mod\;b)}b(bax+y)+(amodb)x=gcd(b,amodb)

不难发现两个式子的形式是一样的,有如下替换关系:
aaa →\rightarrow bbb
bbb →\rightarrow a  mod  ba\;mod\;bamodb
xxx →\rightarrow ⌊ab⌋x+y\lfloor\frac{a}{b}\rfloor x +ybax+y
yyy →\rightarrow xxx

于是我们就可以递归求解这个方程,设该函数为exgcd(a,b,x,y),那么递归到下一层的参数就是exgcd(b,a%b,y,x)(因为x、y都为未知数,所以我们递归时只改变位置即可)。
递归到最底层时,我们式子的形式依然是这样的:
ax+by=gcd(a,b)ax+by=\mathrm{gcd(a,b)}ax+by=gcd(a,b)

由于在递归时,显然a、b一直在做辗转相除,那么最终a会变成gcd,而b会变成0。所以,对于上面的式子x有唯一解x=1,y可以为任意值。一般情况下,题目会要求求最小正整数解,所以我们返回的值就是x=1,y=0。

返回过程中,我们要更改解的值,根据我们推出的两个变换式:
ax+by=gcd(a,b)ax+by=\mathrm{gcd(a,b)}ax+by=gcd(a,b)
b(⌊ab⌋x+y)+(a  mod  b)x=gcd(b,a  mod  b)b(\lfloor\frac{a}{b}\rfloor x +y)+(a\;mod\;b)x=\mathrm{gcd(b,a\;mod\;b)}b(bax+y)+(amodb)x=gcd(b,amodb)

可以得到 : y=y−⌊ab⌋xy=y-\lfloor\frac{a}{b}\rfloor xy=ybax

而我们传参的时候已经改变了x、y的位置,所以返回的时候不用管。

代码如下:

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    b?(exgcd(b,a%b,y,x),y-=a/b*x):(x=1,y=0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值