欧几里得,贝祖定理与扩展欧几里得
欧几里得:
又叫辗转相除法,用于计算两个数a,b的最大公约数
有公式 gcd(a,b)= gcd(b,a%b)
证明:
不妨设a>b(不然递归一次不就一样了吗)
a可以表示成a=k*b +r, r=a%b
①假设d是a,b 的一个公约数,即 d|a, d|b
而r=a-k*b,r/d = a/d –k*b/d = m 可知m为整数,即d|r
因此d也是b, a%b的公约数
②假设d是b,a%b的公约数,则d|b,d| (a-k*b)
也有d|(a-k*b+k*b) -> d|a
即d也是a,b的公约数
因此(a,b)和(b,a%b)的公约数集相同,因此最大公约数也相同
int gcd(int a,int b) { return b == 0 ? a : gcd(b, a % b); }
贝祖定理
若a,b是整数,则存在整数x,y使得ax+by=gcd(a,b)
且有gcd(a,b)是ax+by集合中的最小正整数(若a!=0 或 b!=0)
证明:
若a=b=0,则(a,b)=0,成立
不妨设a≠0, 考虑由a,b所有的线性组合组成的集合I:
I = {ax+by : x,y∈Z }
I中必定存在正元素,设I∩(Z+)=P,则P≠Ø
设P中得最小正整数为d
因为d∈I,所以d是a,b的一个线性组合:∃x,y∈Z
满足 d= ax+by
∃ q,r∈Z使得a=d*q+r ,0<=r<d
假设r>0,则 r=a-qd = a-q(ax+by)=(1-qx)a+(-qy)b ∈P
与d是P的最小元矛盾, 因此r=0 即d是a的因子
同理可得d是b的因子,因此d是a和b的公因子
若c是a和b的任意一个公因子,则设a=ca’, b=cb’
d=ax+by=c(xa’+yb’),所以c|d ,所以|c|<=d
所以d=gcd(a,b)
且可以证明∀ X∈I, 有 d|X
当X=0,显然成立
当X!=0
反证: 若不满足d|X
则存在 X=g*d+r, 0<r<d ,r∈Z
a*x1+b*y1=d
a*g*x1+b*g*y1=g*d ①
a*x2+b*y2=X ②
②-①得 a*(x2-g*x1) + b*(y2-g*y2) = r
与d是最小正整数矛盾
因此∀ X∈I, 有 d|X
扩展欧几里得:
扩展欧几里得提供了一种求ax+by=gcd(a,b)得解(x,y)的方法
求解过程
a*x1+b*y1=gcd(a, b);
b*x2+gcd(a%b)*y2=gcd(b, a%b);
∵gcd(a,
b)==gcd(b, a%b)
∴a*x1+b*y1==b*x2+(a%b)*y2
∵对于a和b存在整数k使得a % b == a -
k * b
∴a%b可以拆成a-k*b,k==(a / b 向下取整)
∴a * x1 + b *
y1 == b * x2 + ( a - k * b ) * y2 ( 把k==(a / b 向下取整)代入 )
∴a * x1 + b * y1 == b * x2 + ( a - ( a / b ) * b ) * y2
即a * x1 + b * y1 == b * x2 + a * y2 - b * ( a / b ) *
y2
所以有a * x1 + b * y1 == a * y2 + b * ( x2 - ( a / b ) *
y2 )
观察上式可知 x1 = y2 , y1 = x2 - a / b * y2
x1,y1是由x2,y2得来的
x2,y2也可以由x3,y3得来的,进行递归,但递归需要终止状态:
在辗转相除法求最大公约数的时候,我们的递归终止条件是一方为0,我们也可以参考一下,
先递归gcd(a , b),当b==0时,此时a的值就是我们要的最大公约数,再根据扩展欧几里得定律a * x + b * y == gcd(a , b),
将a = a,b = 0代入,可以求出x和y的值,此时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 = x; x = y; y = t - a/b*y; return r; }