扩展欧几里得算法

首先是裴蜀定理

对任意两个整数、,设是它们的最大公约数。那么关于未知数xy的线性丢番图方程(称为裴蜀等式):

有整数解(x,y) 当且仅当md 的倍数。裴蜀等式有解时必然有无穷多个解。            

                                              ---By 维基百科

 

 

这可以当结论记着(主要是要会用),如果想知道更多可以去这里:

https://wc.yooooo.us/wiki/%E8%B2%9D%E7%A5%96%E7%AD%89%E5%BC%8F(这是维基百科)

还有就是算法导论的545页的定理31.2的证明(推荐先看这个)

 

 还有一个结论:

x = x0 + b/(a,b)*k  (k∈Z)

y = y0 - a/(a,b)*k  (k∈Z)

x0,y0为ax+by的任意一组解

这个结论告诉我们只要求出一组解就可以求出所有解,而且有无数个解

 

接下来是扩展欧几里得算法

通过这个算法我们可以求得ax+by=gcd(a,b)的一组解

 

 

证明:设 a>b。

  推理1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;//推理1

  推理2,ab!=0 时

  设 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;

  根据恒等定理得:x1=y2; y1=x2-(a/b)*y2;//推理2

     这样我们就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.

   上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。

 

可以不看上面的证明,它想让我们知道的就是bx2+(a mod b)y2=gcd(b,a mod b)的x2,y2,可以推出x1,y1的解(好像我只是复述了一下)

对于这个x2,y2有b'x3+(a' mod b')y3=gcd(b',a' mod b'),

对于这个x3,y3有.......

直到b = 0,x = 1,y = 0

然后往上递推

 

代码:

int exgcd(int a,int b,int & x,int & y){
	if(b == 0){
		x = 1;
		y = 0;
		return a;
	}
	int r = exgcd(b, a%b, x, y);
	int t = y;
	y = x - (a/b)*y;
	x = t;
	return r;
}

 短一点的代码:

int extgcd(int a,int b,int& x.int& y){
	int d = a;
	if (b != 0){
			d = extgcd(b,a % b,y,x);
			y -=(a/b)*x;
		}
	else  {
			x = 1;y = 0;
		}
	return d;
}

 

再短一点的代码:

1 void extgcd(int a,int b,int& x.int& y){ 2     if (b != 0){ 3             extgcd(b,a % b,y,x); 4             y -=(a/b)*x; 5  } 6     else { 7             x = 1;y = 0; 8  } 9 }

这短得都可以背了.......

 

 

最后是线性同余方程:

首先贴个百科,介绍一下什么是线性同余方程:

https://wc.yooooo.us/wiki/%E7%BA%BF%E6%80%A7%E5%90%8C%E4%BD%99%E6%96%B9%E7%A8%8B

根据百科所讲我们可以用扩展欧几里得算法求得r,然后求得特殊解,从而求出通解

 

你可能感兴趣的:(扩展欧几里得算法)