首先让我们先来普及一下,关于gcd的知识,这里几个字就可以搞定,gcd(a,b)就是指a,b的最大公约数,我靠,你可能会说这个有什么用呢?
不要着急,我们马上就会进行讲解:
首先先来普及一些基本概念:
首先他们必须满足贝祖等式(好高大上的名字啊!): ax+by = gcd(a, b)。
于是由这个定理,我们成功推出了:(说实话我TM也没有听懂是怎么推的,呵呵!)
所以,我们由gcd函数的知识,可以成功的推出,如下两个递归时的方程:
ax+by=gcd(a,b);
因为a=a%b+(a/b)*b;
带入化简后:b((a/b)*x+y)+(a%b)*x=gcd(b,a%b);
下面为证明过程:
设:a>b。
推理1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
//-------------------------------------------------------------
推理2,ab!=0 时
设 ax+by=gcd(a,b);
//important
bx1+(a%b)y1=gcd(b,a%b);
根据正常欧几里德原理有 gcd(a,b)=gcd(b,a%b);
则:ax+by=bx1+(a%b)y1;
因为a=a%b+(a/b)*b;
代入
即:ax+by=bx1+(a-(a/b)*b)y1=ay1+bx1-(a/b)*by1=ay1+b(x1-(a/b)*y1);
由此得:x=y1 ,y=x1-(a/b)*y1;
//-------------------------------------------------------------
这样我们就得到了求解 x,y 的方法:x,y 的值基于 x1,y1.
\上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
这个推理应该非常的完美了吧!
我认为这份推理很不错的诠释了我给lry讲了半天的东西是怎么来的(因为他设了两个变量),所以讲的非常清楚,点赞!
那么相信大家gcd应该是没有什么问题了:
下面是代码实现:
void gcd(int a,int b ,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
}
else
{
gcd(b,a%b,x,y);
int swap;
swap=y;
y=x-(a/b)*y;
x=swap;
}
}
附件(网络资料):
听说有非递归版!
http://anh.cs.luc.edu/331/notes/xgcd.pdf
http://math.cmu.edu/~bkell/21110-2010s/extended-euclidean.html
如果你还是没有看懂
下面有从《计算机程序设计艺术》转载的证明方法,仅供参考:
证明(1):
算法首次转到E2时,由上表,显然等式成立。
步骤 E2,E3 并不会改变等式的正确性。
所以只需要证明步骤 E4 不改变他们的正确性就可以了。执行 E4 之前,
a'm + b'n = c(*)
am + bn = d(**)
成立。
a'm + b'n = c = qd + r;
a'm + b'n - q(am + bn) = r;
(a' - qa)m + (b' - qb)n = r(***)执行 E4 之后,c←d, d←r, t←a', a'←a, a←t-qa, t←b', b'←b, b←t-qb;
所以
(**)变为 a' + b' = c
(***)变为 am + bn = d
所以步骤 E4 不改变等式的正确性,得证。
下面强势给出非递归版代码:(我也好像有点懂!)
int exgcd(int m, int n, int &x, int &y) {
if (n == 0) {
x = 1;
y = 0;
return m;
}
int a, a1, b, b1, c, d, q, r, t;
a1 = b = 1;
a = b1 = 0;
c = m;
d = n;
q = c/d;
r = c%d;
while (r) {
c = d;
d = r;
t = a1;
a1 = a;
a = t - q * a;
t = b1;
b1 = b;
b = t - q * b;
q = c/d;
r = c%d;
}
x = a;
y = b;
return d;
}
(以上代码为转载)
相关练习题
P1082 同余方程
另一篇洛谷博客:
【扩展欧几里德算法(gcd扩展使用)】简单的欧几里德拓展
推荐阅读
- AIoT(人工智能+物联网)|程序员的数学【线性代数基础】
- topcoder|Topcoder SRM 661 Div1 Easy: MissingLCM
- HDU 5184 Brackets (卡特兰数)
- 高斯消元
- 水题纪念|【51nod - 1098】 最小方差(基础数学,公式化简,前缀和,积的前缀和)
- 数学|CF 514D.Nature Reserve 几何,二分,交集
- codeforces|Codeforces Round #665 (Div. 2) C. Mere Array(数学)
- codeforces|Codeforces Round #665 (Div. 2) A. Distance and Axis(思维,数学)
- 数论|Codeforces Global Round 10 B. Omkar and Infinity Clock(数学)