#朴素的欧几里得算法大家应该知道
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)表示a,b的最大公约数
朴素的欧几里得算法其实就是所谓的辗转相除法
- 辗转相除法
g c d ( a , b ) = g c d ( b , a gcd(a,b)=gcd(b,a gcd(a,b)=gcd(b,a m o d mod mod b ) b) b)
证明如下:
设 r = a 设r=a 设r=a m o d mod mod b b b = a − ⌊ a b ⌋ ∗ b =a-\lfloor\frac{a}{b}\rfloor*b =a−⌊ba⌋∗b, p = g c d ( a , b ) p=gcd(a,b) p=gcd(a,b);
则 a = x p , b = y p a=xp,b=yp a=xp,b=yp
代入可得 r = x p − ⌊ x p y p ⌋ ∗ y p r=xp-\lfloor\frac{xp}{yp}\rfloor*yp r=xp−⌊ypxp⌋∗yp
提公因式得 r = p ( x − ⌊ x p y p ⌋ ∗ y ) r=p(x-\lfloor\frac{xp}{yp}\rfloor*y) r=p(x−⌊ypxp⌋∗y)
所以 p ∣ r p|r p∣r
即 a , b 的 最 大 公 约 数 也 是 r 的 约 数 a,b的最大公约数也是r的约数 a,b的最大公约数也是r的约数
设 p ‘ = g c d ( b , r ) p`=gcd(b,r) p‘=gcd(b,r)
则 b = x ‘ p ‘ , r = y ‘ p ‘ b=x`p`,r=y`p` b=x‘p‘,r=y‘p‘
a = r + ⌊ a b ⌋ ∗ b a=r+\lfloor\frac{a}{b}\rfloor*b a=r+⌊ba⌋∗b
代入得 a = y ‘ p ‘ + ⌊ a b ⌋ ∗ x ‘ p ‘ a=y`p`+\lfloor\frac{a}{b}\rfloor*x`p` a=y‘p‘+⌊ba⌋∗x‘p‘
提公因式 a = p ‘ ( y ‘ + ⌊ a b ⌋ ∗ x ‘ ) a=p`(y`+\lfloor\frac{a}{b}\rfloor*x`) a=p‘(y‘+⌊ba⌋∗x‘)
所以 p ‘ ∣ a p`|a p‘∣a
得出结论:a,b与b,a mod b的公约数相同,所以最大公约数也相同
得证;
Code:
int gcd(int a,int b)
{
if(!b) return a;
else return gcd(b,a%b);
}
扩展欧几里得算法
扩展欧几里得算法就是在朴素的欧几里得算法上求一组未知数(x,y)的解,满足贝祖定理: a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
- 公式的推导
当且仅当 a > b a>b a>b
① b = 0 b=0 b=0 则 x = 1 , y = 0 x=1,y=0 x=1,y=0
② a > b > 0 a>b>0 a>b>0
设 a x 1 + b y 1 = g c d ( a , b ) ; b x 2 + ( a ax1+by1=gcd(a,b);bx2+(a ax1+by1=gcd(a,b);bx2+(a m o d mod mod b ) y 2 = g c d ( b , a b)y2=gcd(b,a b)y2=gcd(b,a m o d mod mod b ) b) b)
由朴素欧几里得算法得: g c d ( a , b ) = g c d ( b , a gcd(a,b)=gcd(b,a gcd(a,b)=gcd(b,a m o d mod mod b ) b) b)
所以 a x 1 + b y 1 = b x 2 + ( a ax1+by1=bx2+(a ax1+by1=bx2+(a m o d mod mod b ) y 2 b)y2 b)y2
即 a x 1 + b y 1 = b x 2 + ( a − ⌊ a b ⌋ ∗ b ) y 2 ax1+by1=bx2+(a-\lfloor\frac{a}{b}\rfloor*b)y2 ax1+by1=bx2+(a−⌊ba⌋∗b)y2
化简得: a x 1 + b y 1 = b x 2 + a y 2 − ⌊ a b ⌋ ∗ b ∗ y 2 ax1+by1=bx2+ay2-\lfloor\frac{a}{b}\rfloor*b*y2 ax1+by1=bx2+ay2−⌊ba⌋∗b∗y2
由贝祖等式得 x 1 = y 2 y 1 = x 2 − ⌊ a b ⌋ ∗ b . \\x1=y2\\ {y1=x2-\lfloor\frac{a}{b}\rfloor*b} . x1=y2y1=x2−⌊ba⌋∗b.
Code:
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 z=x;
x=y;y=z-a/b*y;
return r;
}
扩展欧几里得应用
①解不定方程
②解线性同余方程
③求模的逆元
1.解形如ax+by=c的不定方程
用扩展欧几里得算法求出解
a
x
‘
+
b
y
‘
=
g
c
d
(
a
,
b
)
ax`+by`=gcd(a,b)
ax‘+by‘=gcd(a,b)
再分别乘上
c
g
c
d
(
a
,
b
)
\frac{c}{gcd(a,b)}
gcd(a,b)c
当
c
c
c
m
o
d
mod
mod
g
c
d
(
a
,
b
)
≠
0
gcd(a,b)\neq0
gcd(a,b)=0时无解
2.解形如 a x ≡ b ( m o d ax\equiv b(mod ax≡b(mod m ) m) m)的线性同余方程
即
a
x
−
m
y
=
b
ax-my=b
ax−my=b
a
x
+
m
(
−
y
)
=
b
ax+m(-y)=b
ax+m(−y)=b
得出:
a
x
+
m
y
=
b
ax+my=b
ax+my=b
同上解除即可。
3.求 a x ≡ 1 ( m o d ax\equiv1(mod ax≡1(mod m ) m) m)
由上式子可得
x
≡
1
a
(
m
o
d
x\equiv \frac{1}{a} (mod
x≡a1(mod
m
)
m)
m)
所以 x是a的逆元
同②得:
a
x
+
m
y
=
1
ax+my=1
ax+my=1
解出x即可.