基础欧几里得算法
又称辗转相除法,公式:gcd(a,b)=gcd( a , b )。(a>b)
一下搬运自百度百科
证法一
a可以表示成a = kb + r(a,b,k,r皆为正整数,且r<b),则r = a mod b
假设d是a,b的一个
公约数,记作d|a,d|b(a可整除d,b也可以整除d),即a和b都可以被d整除。
而r = a - kb,两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数,因此d|r
因此d也是b,a mod b的公约数
假设d是b,a mod b的公约数, 则d|b,d|(a-k*b),k是一个整数。
进而d|a.因此d也是a,b的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证。
证法二
第一步:令c=gcd(a,b),则设a=mc,b=nc
第二步:可知r =a-kb=mc-knc=(m-kn)c
第三步:根据第二步结果可知c也是r的
因数
第四步:可以断定m-kn与n互素【否则,可设m-kn=xd,n=yd,(d>1),则m=kn+xd=kyd+xd=(ky+x)d,则a=mc=(ky+x)dc,b=nc=ycd,故a与b最大公约数≥cd,而非c,与前面结论矛盾】
从而可知gcd(b,r)=c,继而gcd(a,b)=gcd(b,r),得证
模P
乘法逆元(在筛素数的时候也会用到)
对于整数a、p,如果存在整数b,满足ab mod p =1,则说,b是a的模p乘法逆元。
定理:a存在模p的乘法逆元的充要条件是gcd(a,p) = 1
证明:
首先证明充分性
如果gcd(a,p) = 1,根据
欧拉定理,aφ(p) ≡ 1 mod p,因此
显然aφ(p)-1 mod p是a的模p乘法逆元。
再证明必要性
假设存在a模p的乘法逆元为b
ab ≡ 1 mod p
则ab = kp +1 ,所以1 = ab - kp
因为gcd(a,p) = d
所以d | 1
所以d只能为1
扩展欧几里德算法
用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a,b)=gcd(a,a mod b),直接根据数学推算出递归的x,y方程
求解 x,y的方法的理解
设 a>b。
1,显然当 b=0,gcd(a,b)=a。此时 x=1,y=0;
2,a>b>0 时
设 ax
1+ by
1= gcd(a,b);
bx
2+ (a mod b)y
2= gcd(b,a mod b);
根据朴素的
欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则:ax
1+ by
1= bx
2+ (a mod b)y
2;
即:ax
1+ by
1= bx
2+ (a - [a / b] * b)y
2=ay
2+ bx
2- [a / b] * by
2;
说明: a-[a/b]*b即为mod运算。[a/b]代表取小于a/b的最大整数。
也就是ax
1+ by1 == ay
2+ b(x
2- [a / b] *y
2);
根据恒等定理得:x
1=y
2; y
1=x
2- [a / b] *y
2;
这样我们就得到了求解 x
1,y
1 的方法:x
1,y
1 的值基于 x
2,y
2.
上面的思想是以递归定义的,因为 gcd 不断的递归求解一定会有个时候 b=0,所以递归可以结束。
pascal算法实现
function gcd(a,b,x,y:longint;)
var t:longint;
begin
if b=0 then
begin
x:=1; y:=0;
exit(a);
end;
gcd:=gcd(b,a mod b,y,x);
y:=y-(a div b)*x; //百度百科上x,y的位置有调换,注意
end;