注意:以下假设a>b>0且a,b均为整数,但计算过程中以b=0为结束标志,因此下面可能会出现b=0,gcd(a,b)表示求a,b的最大公约数
① 欧几里得定理
公式:gcd(a,b)=gcd(b,a%b)(此处假设a%b!=0)
我的证明:
可设gcd(a,b)=c;
则有a=m*c,b=n*c,r=a%b,其中gcd(m,n)=1;
必存在r=a-b*k,其中b*k=<a<b*(k+1);
r=m*c-n*c*k=(m-n*k)*c;
则gcd(b,r)=gcd(n*c,(m-n*k)*c);
若gcd(n,m-n*k)!=1,则gcd(m,n)!=1也成立,与前面假设矛盾;
说明gcd(n*c,(m-n*k)*c)=c;
即证gcd(a,b)=gcd(b,a%b);
求最大公约数的辗转相除法就是应用上述原理了
递归形式辗转相除法的gcd(a,b):
<span style="font-size:24px;">int gcd(int m,int n)
{
if(!n)
return m;
return gcd(n,m%n);
}</span>
非递归形式辗转相除法的gcd(a,b)
<span style="font-size:24px;">int gcd(int m,int n)
{
while(n)
{
int t;
t=n;
n=m%n;
m=t;
}
return m;
}</span>
② 扩展欧几里得定理
公式:gcd(a,b)=a*x+b*y(x,y为整数)
我的证明:
按照上述①的递归算法求最大公约数的时候,最后必然会出现gcd(a,0),所以。。
先看看gcd(a,b)=a*x+b*y,b=0的解,显然可得出x=1,y=0为其一种解。(当然y也可以取他任意的值,不影响结果)
好了,在gcd(a,b)的求解最后必然会出现一组解满足gcd(a,b)=a*x+b*y。
假设命题成立
则有存在x1,y1,使gcd(a,b)=a*x+b*y成立
存在x2,y2,使gcd(b,a%b)=b*x+(a%b)*y成立
代入
gcd(a,b)=a*x1+b*y1=c;
gcd(b,a%b)=b*x2+(a%b)*y2=c;
又:a%b=a-(a/b)*b
代入:
a*x1+b*y1=b*x2+(a-a/b*b)*y2=a*y2+b*(x2-a/b*y2)
可得:x1=y2,y1=x2-a/b*y2;
说明:只要 gcd(b,a%b)=b*x+(a%b)*y存在解,则gcd(a,b)=a*x+b*y必有解
前面已证明:求解的最后一定会出现一组解,不断迭代上去就会产生真正的一组解满足:
gcd(a,b)=a*x+b*y;
看下面的代码帮助理解
递归形式的:
<span style="font-size:24px;">int gcd(int a,int b,int &x,int &y)//注意是x,y的引用,也可以把x,y定义为全局变量
{
if(!b)
{
x=1;
y=0;
return a;
}
int ma=gcd(b,a%b,x,y);//递归求出最大公约数,和x2,y2
int temp=x;//以下就是推的公式了
x=y;
y=temp-(a/b)*x;
return ma;
}
</span>
非递归形式的:=_=不会写~_~!;
进一步的,那么gcd(a,b)=a*x+b*y的一般解是什么呢?应用②求出一组解x0,y0;
则有:
x=x0+b/c*t
y=y0-a/c*t;(t为任意整数)
c=gcd(a,b);a=c*m;b=c*n;
证明:
已知 a*x0+b*y0=c;
设通解 x=x0+p,y=y0+q;
则有a*(x0+p)+b*(y0+q)=c;
得:a*p+b*q=0;
注:下面的a/b表示的是分式而不是除
a/b=q/(-p)=m/n;
可以看出q=m*t,p=(-n)*t,t为任意整数;
x=x0+p=x0+(-b/c)*t;
y=y0+q=y0+(a/c)*t;
注意:那个”-“可以给q也可以给p;
现在我们就可以快乐的解不定方程啦^_^!