扩展欧几里得算法
首先是裴蜀定理
对任意两个整数
、
,设
是它们的最大公约数。那么关于未知数
和
的线性丢番图方程(称为裴蜀等式):
有整数解(x,y) 当且仅当m 是d 的倍数。裴蜀等式有解时必然有无穷多个解。
---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,然后求得特殊解
,从而求出通解

、
,设
是它们的
和
的
浙公网安备 33010602011771号