
例题:利用扩展欧几里得算法思想求得不定方程 ax+by=gcd(a,b) 的一组解
它还可以用来求除法逆元。
欧几里得算法
通俗地讲就是辗转相除法。
若有两个数a和b,求两个数的公因数。
可以枚举两个数的因子,复杂度为O(n),数据大的时候就很慢了。
于是便有了欧几里得算法:gcd(a,b)=gcd(b,a mod 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 = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等。
复杂度为O(log min(a,b)).
代码
1 |
int gcd(int a, int b) |
扩展欧几里得算法
利用欧几里得算法思想求得不定方程 ax+by=gcd(a,b) 的一组解。
原理如下:
设a>b
1)当b=0有 ax=gcd(a,b)=a,即x=1,而y为任意数,为了统一我们令y=0;
2)接下来看一组方程:
方程一 : ax1+by1=gcd(a,b)
方程二 : bx2+(a%b)y2=gcd(b,a%b) (方程二由欧几里得算法 gcd(a,b) =gcd(b,a%b) 得到)
两个等式右边相等,所以 ax1+by1 = bx2+(a%b)y2
又a%b=a-floor(a/b)b (这里floor的意思是向下取整,在c++代码中int类型可以不用floor)
得ax1+by1=bx2+[a-floor(a/b)b]y2
在这里把a,b当成未知数,根据多项式恒等定理由x1a+y1b=y2a+[x2-floor(a/b)y2]b可得
x1=y2
y1=[x2-floor(a/b)y2]
由最终解x=1,y=0不断向前推出目标解x1,y1
不难想到利用递归求解,根据上述过程得到以下代码
代码
1 |
#include <iostream> |
关于除法逆元,请看其他博客。




近期评论