1. 称c为a和b的最大公共因子,如果
(1).c是a和b的因子。
(2).a和b的任何其它公共因子都是c的因子。
即gcd(a,b)=max[k,其中k|a且k|b]
最大公共因子肯定是正数,所以gcd(a,b)=gcd(|a|,|b|)
2.根据gcd(a,b)=gcd(|a|,|b|),各种情况都可转化为求2个非负整数的最大因子,不妨假设a>=b>=0,并定义gcd(0,0)=0。
假设d是a,b的任意一个公共因子,即d|a && d|b
用b除a可得
a=qb+r 0<=r<b
根据d|a和d|b可以推出d|(a-qb),即d|r,d是b,r的公共因子。
另一方面假设d'是r和b的公共因子,推出d|(qb+r),d是a,b的公共因子。
所以a,b的公共因子集合和b,r的公共因子集合相同,故gcd(a,b)=gcd(b,r)=gcd(b,a mod r)
因为b<a且 (a mod r)<b所以算法收敛。
3.根据算法写出如下代码
4.扩展的Euclid算法。
对给定的Euclid算法不仅算出gcd(a,b),而且算出另外两个整数它们满足
ax+by=d=gcd(a,b)
假设每次除法可以找到xi和yi满足ri=axi+byi,每步计算如下:
a=q1b + r1 r1=ax1 + by1
b=q2r1 + r2 r2=ax2 + by2
r1=q3r2 + r3 r3=ax3 + by3
....
rn-2=qnrn-1 + rn rn=axn + byn
rn-1=qn+1rn + 0
移项得
ri=ri-2 - ri-1qi
而
ri-1=axi-1 + byi-1
ri-2=axi-2 + byi-1则ri=a(xi-2 - qixi-1) + b(yi-2 - qiyi-1)
和ri=axi + byi比较得
xi= xi-2 - qixi-1 yi = yi-2 - qiyi-1
5.根据4.的递推关系可以写出对应程序如下:
6.特别地,如果a,b互素,gcd(a,b)=1,则
ax+by=1
移项ax=1+(-by),ax mod b=1,x是a的模b乘法逆员,同样y是b的模a乘法逆元。
乘法逆元的一个应用,ACM有时候用到
当我们要求(a/b) mod p的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
我们可以通过求b关于p的乘法逆元k,将a乘上k再模p,即(a*k) mod p。其结果与(a/b) mod p等价。
证:(其实很简单。。。)
根据b*k≡1 (mod p)有b*k=p*x+1。
k=(p*x+1)/b。
把k代入(a*k) mod p,得:
(a*(p*x+1)/b) mod p
=((a*p*x)/b+a/b) mod p
=[((a*p*x)/b) mod p +(a/b)] mod p
=[(p*(a*x)/b) mod p +(a/b)] mod p
//p*[(a*x)/b] mod p=0
所以原式等于:(a/b) mod p
(1).c是a和b的因子。
(2).a和b的任何其它公共因子都是c的因子。
即gcd(a,b)=max[k,其中k|a且k|b]
最大公共因子肯定是正数,所以gcd(a,b)=gcd(|a|,|b|)
2.根据gcd(a,b)=gcd(|a|,|b|),各种情况都可转化为求2个非负整数的最大因子,不妨假设a>=b>=0,并定义gcd(0,0)=0。
假设d是a,b的任意一个公共因子,即d|a && d|b
用b除a可得
a=qb+r 0<=r<b
根据d|a和d|b可以推出d|(a-qb),即d|r,d是b,r的公共因子。
另一方面假设d'是r和b的公共因子,推出d|(qb+r),d是a,b的公共因子。
所以a,b的公共因子集合和b,r的公共因子集合相同,故gcd(a,b)=gcd(b,r)=gcd(b,a mod r)
因为b<a且 (a mod r)<b所以算法收敛。
3.根据算法写出如下代码
int Euclid(int a,int b)
{
if(b==0)
return a;
else
return Euclid(b,a%b);
}
非递归版本
int euclid(int a,int b)
{
int tem;
while(b)
{
tem = b;
b = a%b;
a = tem;
}
return a;
}
4.扩展的Euclid算法。
对给定的Euclid算法不仅算出gcd(a,b),而且算出另外两个整数它们满足
ax+by=d=gcd(a,b)
假设每次除法可以找到xi和yi满足ri=axi+byi,每步计算如下:
a=q1b + r1 r1=ax1 + by1
b=q2r1 + r2 r2=ax2 + by2
r1=q3r2 + r3 r3=ax3 + by3
....
rn-2=qnrn-1 + rn rn=axn + byn
rn-1=qn+1rn + 0
移项得
ri=ri-2 - ri-1qi
而
ri-1=axi-1 + byi-1
ri-2=axi-2 + byi-1则ri=a(xi-2 - qixi-1) + b(yi-2 - qiyi-1)
和ri=axi + byi比较得
xi= xi-2 - qixi-1 yi = yi-2 - qiyi-1
5.根据4.的递推关系可以写出对应程序如下:
int exEuclid(int a,int b,int& x,int& y)
{
int r1,r2,x1,x2,y1,y2,q;
int rtem,xtem,ytem;
r1=a;
r2=b;
x1=1;y1=0;
x2=0;y2=1;
while(r2!=0)
{
rtem=r1%r2;
q=(r1-rtem)/r2;
r1=r2;
r2=rtem;
if(r2==0)
break;
xtem=x1-q*x2;
x1=x2;
x2=xtem;
ytem=y1-q*y2;
y1=y2;
y2=ytem;
}
x=x2;
y=y2;
return r1;
}
6.特别地,如果a,b互素,gcd(a,b)=1,则
ax+by=1
移项ax=1+(-by),ax mod b=1,x是a的模b乘法逆员,同样y是b的模a乘法逆元。
乘法逆元的一个应用,ACM有时候用到
当我们要求(a/b) mod p的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
我们可以通过求b关于p的乘法逆元k,将a乘上k再模p,即(a*k) mod p。其结果与(a/b) mod p等价。
证:(其实很简单。。。)
根据b*k≡1 (mod p)有b*k=p*x+1。
k=(p*x+1)/b。
把k代入(a*k) mod p,得:
(a*(p*x+1)/b) mod p
=((a*p*x)/b+a/b) mod p
=[((a*p*x)/b) mod p +(a/b)] mod p
=[(p*(a*x)/b) mod p +(a/b)] mod p
//p*[(a*x)/b] mod p=0
所以原式等于:(a/b) mod p