算法总结之欧几里德算法

算法总结之欧几里德算法

1.欧几里德算法

  欧几里德算法又称辗转相除法,用于计算两个正整数a,b的最大公约数。

  其计算原理依赖于下面的定理:

  gcd(a,b) = gcd(b,a mod b) (a>b 且a mod b 不为0)

代码实现:

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

2.扩展欧几里德算法

基本算法:

  对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y,使得 gcd(a,b)=ax+by。
证明:
  则我们先来假设方程的ax+by=gcd(a,b)=d的一个正整数解为x1,y1;别怀疑,这个方程一定有解

  则有ax1+by1=gcd(a,b)   (1)

  又对于方程bx +(a%b)y =gcd(b,a%b)有解x2,y2(假设)

  则有bx2+(a%b)y2=gcd (b,a%b) = gcd(a, b) (2)

  又a%b = a - (a/b)*b;

  则(2)式变为bx2+(a-(a/b)*b)y2=gcd(a,b);

  即 ay2 + b(x2-(a/b)*y2) = gcd (a,b) (3) ;

  对比(1)(3)得

  x1=y2;y1=x2-(a/b)*y2

  故,ax+by=gcd(a,b)的解只需要在方程bx+(a%b)y=gcd(b,a%b)的解的基础上进行简单的运算就变成原来方程的解,

  因为gcd不断递推时会有b=0的情况出现,故可以通过递推来得到方程的解。

代码实现:

 1 LL extended_gcd(LL a,LL b,LL &x,LL &y) //返回值为gcd(a,b)
 2 {
 3     LL ret,tmp;
 4     if (b==0)
 5     {
 6         x=1,y=0;
 7         return a;
 8     }
 9     ret=extended_gcd(b,a%b,x,y);
10     tmp=x;
11     x=y;
12     y=tmp-a/b*y;
13     return ret;
14 }

3.一些结论

  1) 方程 Ax+By=C 满足条件:C=K*Gcd(A,B) (K为整数) 则方程存在整数解。反之无解。

  2) 设a,b,c为任意整数。若方程ax+by=c的一组整数解为(x0,y0),则它的任意整数解都可以写成(x0+kb‘,y0-ka‘),其中a‘=a/gcd(a,b),b‘=b/gcd(a,b),k为任意整数。

  3) 若求出一组整数解(x1,x2) 设x0=x1%b‘ y0=y1%b‘ 则x0,y0为所有解中最接近零的解。

算法总结之欧几里德算法,布布扣,bubuko.com

时间: 2024-12-19 19:13:23

算法总结之欧几里德算法的相关文章

欧几里德算法与扩展欧几里德算法

欧几里得算法就是我们常说的辗转相除法,辗转相除法可以用来求最大公约数,知道最大公约数还可以求最小公倍数.gcd在好像也有库函数__gcd int Gcd(int a, int b) { while(b != 0) { int r = b; b = a % b; a = r; } return a; } 非递归方法 int gcd(int a,int b) {return b ? gcd(b,a%b) : a;} 递归方法 扩展欧几里得算法是在解决一个什么问题呢,解方程,解二元一次方程的通解. 扩

扩展欧几里德算法

文章来源:http://blog.csdn.net/zhjchengfeng5/article/details/7786595 谁是欧几里德?自己百度去 先介绍什么叫做欧几里德算法 有两个数 a b,现在,我们要求 a b 的最大公约数,怎么求?枚举他们的因子?不现实,当 a b 很大的时候,枚举显得那么的na?ve ,那怎么做? 欧几里德有个十分又用的定理: gcd(a, b) = gcd(b , a%b) ,这样,我们就可以在几乎是 log 的时间复杂度里求解出来 a 和 b 的最大公约数了

欧几里德与扩展欧几里德算法(转)

欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a

HDU 1098 Ignatius's puzzle 费马小定理+扩展欧几里德算法

题目大意: 给定k,找到一个满足的a使任意的x都满足 f(x)=5*x^13+13*x^5+k*a*x 被65整除 推证: f(x) = (5*x^12 + 13 * x^4 + ak) * x 因为x可以任意取 那么不能总是满足 65|x 那么必须是 65 | (5*x^12 + 13 * x^4 + ak) 那么就是说 x^12 / 13 + x^4 / 5 + ak / 65 正好是一个整数 假设能找到满足的a , 那么将 ak / 65 分进x^12 / 13 + x^4 / 5中得到

POJ 2773 Happy 2006 (分解质因数+容斥+二分 或 欧几里德算法应用)

Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 10309   Accepted: 3566 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7, 9...are a

如何使用循环而不是递归反推的方式实现拓展欧几里德算法

平常我们使用拓展欧几里德算法求pm + qn = gcd(m, n)这种表示时,一般都会选择递归的方式来实现,因为欧几里得算法的递归深度最多也只有O(lgn), according to lame's theorem,所以这个递归用栈是可以忽略的. 但其实只需要循环就可以求出一组pm + qn = gcd(m, n)的表示,将栈深度保持在O(1),这样的写法在使用函数调用的高级语言中看起来复杂一点但在汇编编程时就显得比较简单. 方法是假设第k次迭代中的两个数分别为 M(k) 和 N(k),我们始

ACM数论之旅4---扩展欧几里德算法(欧几里德(???)?是谁?)

为什么老是碰上 扩展欧几里德算法 ( •?∀•? )最讨厌数论了 看来是时候学一学了 度娘百科说: 首先, ax+by = gcd(a, b) 这个公式肯定有解 (( •?∀•? )她说根据数论中的相关定理可以证明,反正我信了) 所以 ax+by = gcd(a, b) * k 也肯定有解 (废话,把x和y乘k倍就好了) 那么已知 a,b 求 一组解 x,y 满足 ax+by = gcd(a, b) 这个公式 1 #include<cstdio> 2 typedef long long LL;

欧几里德与扩展欧几里德算法

转自网上大牛博客,讲的浅显易懂. 原文地址:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 欧几里德算法 欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 第一种证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有

欧几里德算法(最大公约数算法)完整分析

欧几里德算法又称为辗转相除法,用于计算两个非负整数的最大公因数.其伪代码如下: gcd(a, b) //要求保证传入的a>=b if(b == 0) return a return gcd(b, a % b) 首先说明这个函数能返回a与b的最大公因数.但是我们不从代码到原理,我们要从原理返回代码.(下面的出现的所有符号均为非负整数) 在a与b均非0且a>=b的情况下,若c是a和b的最大公因数(c>0),那么就有c|a和c|b的同时成立.显然a=i*c,b=j*c,此处应满足1<=j