欧几里得算法
欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:gcd(a,b)=gcd(a,a mod b)
gcd函数就是用来求(a,b)的最大公约数的。
证明gcd(a,b)=gcd(a,a mod b)
设d为a,b的公约数,则有
设
所以d|r
即(a,b)的公约数是(b,a mod b)的公约数
设d’为b, a mod b 的公约数,则
因为
所以
即(b,a mod b)的公约数是的(a,b)公约数
所以(b,a mod b),(a,b)公约数相同,其最大公约数也相同
code
int gcd(int a,int b) {
int c;
while (b!=0) {
c=a%b;a=b;b=c;
}
return a;
}
扩展欧几里得
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据裴蜀定理)。扩展欧几里德常用在求解模线性方程及方程组中。
分析:
设
当
所以此时
;
当
时
设
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则
;
即
;
根据恒等定理得:
恒等定理:两个多项式相等,则这两多项式最高次数相同,且对应次数项的系数相同.
通过递归我们可以不断的推出x1,y1,最终达到求解ax+by=gcd(a,b)的目的。
code:
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 z=x;
x=y;y=z-a/b*y;
return r;
}
扩展欧几里得的应用
扩展欧几里得的应用主要有三个方面:
- 解不定方程
- 求解线性同余方程
- 求模的逆元
1、解不定方程
求解不定方程ax+by=c
用扩展gcd求出
的解
分别乘上
则可得到ax+by=c的一组解x,y;
当
方程无解
如何求通解?
设
(
为上述过程中解出的特解x,y),且
.
可得
.
又因为
所以p,q应为a,b的公倍数
那么我们可以得到
所以得到通解
因为
所以当
过大时,我们可以将
变为
2、求解线性同余方程
求解:
mod为取余数,那么原式可变为
即
使用前文的方法解 即可
3、求模的逆元
有
同2可得
解出x即为a的逆元