欧几里得、扩展的欧几里得算法

本文详细介绍了欧几里得算法及其扩展版本用于求解最大公约数(GCD)的方法,并展示了迭代和递归两种实现方式。同时,文章还探讨了算法的效率问题,并通过实例讲解了如何利用扩展欧几里得算法解决二元一次方程组的整数解问题。
摘要由CSDN通过智能技术生成

 最大公约数(Greatest Common Divisor)

 

欧几里得算法:

定理1:设a,b,c,q都为整数,且b>0。如果 a = q b+c,那么 gcd(a, b) = gcd(b, c)

证明方法用了集合的方法,就是说明一个的约数必定是另一个数的约数,从而两个数相等。

 

用这个定理就可以写出欧几里得算法

(1)迭代版本

(2)递归版本

 

显然,递归的比迭代的写起来方便,不容易错,但是效率是否会差很多呢?

 

定理2:(由法国数学家拉梅证明)欧几里得算法所需除法次数不超过m和n中较小的那个数的十进制位数的5倍

定理3:(稍弱点)……不超过2 log(n+1),其中n为较小的数

 

有了上面的定理,有理由相信递归版本的优势,但学的时候两种都要会!

 

 

 

 

拓展的欧几里得算法(Extended Euclidean Algorithm)

可以用来求二元一次方程组的整数解问题

ax + by = m,要求gcd(a, b) = 1,否则两边同除以GCD,最后结果再乘以GCD

(3)迭代的拓展欧几里得算法

 

(4)递归的拓展欧几里得算法

 

递归的容易写,容易记。

 

知道了一个解,该方程的所有整数解都可以表示出来

x = x0 + b k

y = y0 + a k

这样,如果要求最小的正整数解也就可以算出来了!

 

原理:摘自网上

令a1=a/gcd(a,b),b1=b/gcd(a,b),m1=m/gcd(a,b)。如果我们能够首先求出满足a*x1+b*y1=gcd(a,b)这个方程的x1和y1,那么x=x1*m1,y=y1*m1就可以求出来了。由欧几里德算法gcd(a,b)=gcd(b,a%b),所以a*x1+b*y1=gcd(a,b)=gcd(b,a%b)=b*x2+(a%b)*y2,现在只要做一些变形就可以得到扩展欧几里德算法中的用到的式子了。令k=a/b(商),r=a%b(余数),那么a=k*b+r。所以r=a-k*b,带入上式,得到a*x1+b*y1=b*x2+(a-(a/b)*b)y2=a*y2+b*(x2-(a/b)*y2) => x1=y2,y1=x2-(a/b)*y2。有了这两个式子我们就知道了在用欧几里德求最大公约数的时候,相应的参数x,y的变化。现在再回过头来看一下扩展欧几里德算法的代码就很好理解了,实际上扩展欧几里德就是在求a和b的最大公约数的同时,也将满足方程a*x1+b*y1=gcd(a,b)的一组x1和y1的值求了出来。下面代码中突出的部分就是标准的欧几里德算法的代码。

 

应用:

(1)求数对于某个质数的逆元

 

 (2)  USACO 4.1 nuggets 正整数解的存在问题

ax+by=c, where gcd(a,b)=1, a>0, b>0;  a posivesolution exists if c>=a*b
 PROOF:
from Extended Euclidean, we know that there exists a solution ax0+by0=c
**   we want to find xn, yn, where xn>0, yn>0. xn = x0 + b*t, yn = y0 - a*t;
**   -x0/b <= t <= y0/a。for c >= a*b, we know that x0/b+y0/a>=1, so it exists

 

(3)FZU APRIL 排列

注意中间结果可能会超过INT,故用要LONG LONG

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值