欧几里得算法和扩展欧几里得算法

一、欧几里得算法

也叫辗转相除法,关键在于这个恒等式:gcd(a,b) = gcd(b,a % b),它的边界条件是gcd(a,0) = a.

这个虽然是递归,但非常高效,可以证明,gcd递归的层数不超过4.7851lgN + 1.6723,其中N = (a,b).

1 LL gcd(LL a, LL b)
2 {
3     return b == 0 ? a : gcd(b, a % b);
4 }

二、扩展欧几里得算法

过程代码,证明如下(参百度百科):

设 a>b

ax1+ by1= gcd(a,b);

bx2+ (a mod b)y2= gcd(b,a mod b);

根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);则:ax1+ by1= bx2+ (a mod b)y2;

即:ax1+ by1= bx2+ (a - [a / b] * b)y2=ay2+ bx2- [a / b] * by2;
即ax1+ by1 == ay2+ b(x2- [a / b] *y2);
对比左右两边,得x1=y2; y1=x2- [a / b] *y2;
这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
 1 //ax + by = d,且|x|+|y|最小,其中d=gcd(a,b)
2 //即使a, b在int范围内,x和y也有可能超过int范围 3 void exgcd(ll a, ll b, ll &d, ll &x, ll &y) 4 { 5 if (!b){ d = a; x = 1; y = 0;} 6 else{ exgcd(b, a % b, d, y, x); y -= x * (a / b);} 7 }
原文地址:https://www.cnblogs.com/lfri/p/9613893.html