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

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

欧几里得算法:

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

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

扩展欧几里得算法:

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

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

上面两个式子显然是对的,就不给证明了。
代入原式可得:
x ∗ ( a    m o d    b + ⌊ a b ⌋ ∗ b ) + b y = g c d ( b , a    m o d    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    m o d    b ) x + b ( ⌊ a b ⌋ x + y ) = g c d ( b , a    m o d    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    = g c d ( a ,            b ) a\;\;\;\;\;\;x\qquad\;\;\;\;+\qquad b\;\;\;\;\;\; y\;=\mathrm{gcd(a,\;\;\;\;\;b)} ax+by=gcd(a,b)
b ( ⌊ a b ⌋ x + y ) + ( a    m o d    b ) x = g c d ( b , a    m o d    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)

不难发现两个式子的形式是一样的,有如下替换关系:
a a a  → \rightarrow   b b b
b b b  → \rightarrow   a    m o d    b a\;mod\;b amodb
x x x  → \rightarrow   ⌊ a b ⌋ x + y \lfloor\frac{a}{b}\rfloor x +y bax+y
y y y  → \rightarrow   x x x

于是我们就可以递归求解这个方程,设该函数为exgcd(a,b,x,y),那么递归到下一层的参数就是exgcd(b,a%b,y,x)(因为x、y都为未知数,所以我们递归时只改变位置即可)。
递归到最底层时,我们式子的形式依然是这样的:
a x + b y = g c d ( 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。

返回过程中,我们要更改解的值,根据我们推出的两个变换式:
a x + b y = g c d ( a , b ) ax+by=\mathrm{gcd(a,b)} ax+by=gcd(a,b)
b ( ⌊ a b ⌋ x + y ) + ( a    m o d    b ) x = g c d ( b , a    m o d    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 − ⌊ a b ⌋ x y=y-\lfloor\frac{a}{b}\rfloor x y=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、付费专栏及课程。

余额充值