1.欧几里得
- 用途
最大公因数和最小公倍数 定理:
gcd(a,b)=gcd(b,a%b)
证明:
我们令 c=gcd(a,b)
令 a=n∗c , b=m∗c
a%b=a−k∗b=(n−m∗k)∗c ,可知,c也是 a%b 的因子,现在只需证明c是b和a%b的最大因子,用反证法:
假设 gcd(b,a%b)=d>c
设 b=n1∗d , a%b=m1∗d
可推出 a=m1∗d+k1∗b=m1∗d+k1∗n1∗d
从而推出 gcd(a,b)=d
矛盾
证明完毕代码
int gcd(int a,int b)
{
return b==0 ? a : gcd(b,a%b);
}
2.扩展欧几里得算法
扩展欧几里得定理
对于不完全为0的非负整数a,b,gcd(a, b)表示a, b的最大公约数,必定存在整数对x,y,满足 a∗x+b∗y==gcd(a,b) 。用途
求出整数x,y使得 a∗x+b∗y=gcd(a,b)应用
扩展欧几里得主要有三个应用:- 求解不定方程
- 求解模的逆元
- 求解同余方程
- 证明
由于 gcd(a,b)=gcd(b,a%b)
所以 b∗x1+(a%b)∗y1=gcd(a,b)
a%b=a−(a/b)∗b
所以 gcd(a,b)=b∗x1+(a−(a/b)∗b)∗y1
=b∗x1+a∗y1–(a/b)∗b∗y1
=a∗y1+b∗(x1–a/b∗y1)
对于我们所求的x,y使得 ax+by=gcd(a,b)
则有 x=y1
y=x1–a/b∗y1 - 代码
int Exgcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
int ans=Exgcd(b,a%b,x,y);
int temp=x;
x=y;
y-temp-a/b*y;
return ans;
}
3.乘法逆元
定义:
b∗b1≡1(modc) ,那么称 b1 为b模c的乘法逆元。定理:
ab(modc)=a∗b1(modc) ,条件是 b1 存在(或b与c互质)。用途
乘法逆元可以用来求解部分除法的取模问题(分母是一个整数,并且与被取模数互质)
知道了乘法逆元的用途之后关键是怎么求出乘法逆元
b1
的问题,由定义
b∗b1≡1(modc)
可以设:
b∗b1=k∗c+1
=>
b∗b1−k∗c=1=gcd(b,c)
,(因为
b,c互质
)
所以问题就变成了用扩展欧几里得的求
b1和k的问题了
,用前面的扩展欧几里得算法就可以得到