欧几里德算法
本篇文章部分参考于 百度百科和丶Sj 博客
[https://blog.csdn.net/qq_40475868/article/details/80277705]
最大公约数(GCD)
算法原理
g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)
证明
设
a
>
b
a>b
a>b,
k
=
g
c
d
(
a
,
b
)
k=gcd(a,b)
k=gcd(a,b)表示
a
a
a与
b
b
b的最大公约数,有:
{
a
=
c
k
b
=
d
k
(
g
c
d
(
c
,
d
)
=
1
)
\begin{cases}a=ck\\b=dk\end{cases}~(gcd(c,d)=1)
{a=ckb=dk (gcd(c,d)=1)设
p
p
p为正整数,且满足:
r
=
a
%
b
=
a
−
p
b
=
(
c
−
p
d
)
k
r=a\%b=a-pb=(c-pd)k
r=a%b=a−pb=(c−pd)k
c
−
p
d
与
d
c-pd与d
c−pd与d互质,若不然,则存在
m
>
1
m>1
m>1,使得:
{
c
−
p
d
=
x
m
d
=
y
m
(
g
c
d
(
x
,
y
)
=
1
)
\begin{cases}c-pd=xm\\d=ym\end{cases}~(gcd(x,y)=1)
{c−pd=xmd=ym (gcd(x,y)=1)于是有:
{
a
=
c
k
=
(
p
d
+
x
m
)
k
=
(
p
y
+
x
)
m
k
b
=
d
k
=
y
m
k
\begin{cases}a=ck=(pd+xm)k=(py+x)mk\\b=dk=ymk\end{cases}
{a=ck=(pd+xm)k=(py+x)mkb=dk=ymk此时
g
c
d
(
a
,
b
)
=
m
k
gcd(a,b)=mk
gcd(a,b)=mk,与原题矛盾,故
c
−
p
d
与
d
c-pd与d
c−pd与d互质。
所以
r
与
b
r与b
r与b的最大公约数也是
k
k
k:
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
r
)
=
g
c
d
(
b
,
a
%
b
)
=
k
gcd(a,b)=gcd(b,r)=gcd(b,a\%b)=k
gcd(a,b)=gcd(b,r)=gcd(b,a%b)=k
int gcd(int a,int b){
return b ? gcd(b,a%b) : a;
}
最小公倍数(LCM)
证明
设
a
,
b
a,b
a,b为整数,有:
{
a
=
c
⋅
g
c
d
(
a
,
b
)
b
=
d
⋅
g
c
d
(
a
,
b
)
(
g
c
d
(
c
,
d
)
=
1
)
\begin{cases}a=c\cdot{gcd(a,b)}\\b=d\cdot{gcd(a,b)}\end{cases}(gcd(c,d)=1)
{a=c⋅gcd(a,b)b=d⋅gcd(a,b)(gcd(c,d)=1)很明显最小公倍数为:
l
c
m
(
a
,
b
)
=
a
g
c
d
(
a
,
b
)
⋅
b
lcm(a,b)=\frac{a}{gcd(a,b)}\cdot{b}
lcm(a,b)=gcd(a,b)a⋅b
代码实现
int lcm(int a,int b){
return a/gcd(a,b)*b;
}
求二元一次方程的整数特解
- 关于
a
x
+
b
y
=
1
(
g
c
d
(
a
,
b
)
=
1
)
ax+by=1(gcd(a,b)=1)
ax+by=1(gcd(a,b)=1)方程总有整数解
对方程 a x + b y = k ax+by=k ax+by=k两边同时取 a 模:
b y ≡ k ( m o d a ) by\equiv{k}(mod~a) by≡k(mod a)对于 a 的一个完全剩余系 { y } ( y ∈ [ 1 , a ] ) \{y\}(y\in[1,a]) {y}(y∈[1,a]),由于 a 与 b 互质,由费马小定理中的引理2,知 { b y } ( y ∈ [ 1 , a ] ) \{by\}(y\in[1,a]) {by}(y∈[1,a])也是模 a 中的一个完全剩余系,故总存在一个 y 1 ∈ [ 1 , a ] s . t . y_{1}\in[1,a]~s.t. y1∈[1,a] s.t.
b y 1 ≡ 1 ( m o d a ) by_{1}\equiv1(mod~a) by1≡1(mod a)所以 b y 1 = k a + 1 by_{1}=ka+1 by1=ka+1,所以:
a x + b y = a ( − k ) + b y 1 = 1 ax+by=a(-k)+by_{1}=1 ax+by=a(−k)+by1=1即, a x + b y = 1 ax+by=1 ax+by=1总有整数解,且显然 x y < 0 xy<0 xy<0 - 关于
a
x
+
b
y
=
1
(
g
c
d
(
a
,
b
)
=
1
)
ax+by=1(gcd(a,b)=1)
ax+by=1(gcd(a,b)=1)的整数解的无限性
若 ( x 1 , y 1 ) ( x 2 , y 2 ) (x_{1},y_{1})(x_{2},y_{2}) (x1,y1)(x2,y2)是 a x + b y = 1 ax+by=1 ax+by=1的解,那么总有:
a ( x 2 − x 1 ) = b ( y 1 − y 2 ) a(x_{2}-x_{1})=b(y_{1}-y_{2}) a(x2−x1)=b(y1−y2)由于 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,所以:
x 2 − x 1 = k b , y 1 − y 2 = k a ( k 是 整 数 ) x_{2}-x_{1}=kb,y_{1}-y_{2}=ka(k是整数) x2−x1=kb,y1−y2=ka(k是整数)所以:
{ x 2 = x 1 + k b y 2 = y 1 − k a \begin{cases}x_{2}=x_{1}+kb\\y_{2}=y_{1}-ka\end{cases} {x2=x1+kby2=y1−ka由于 k 是可以任意取的,所以原方程的解有无限个。 - 关于
a
x
+
b
y
=
1
(
g
c
d
(
a
,
b
)
=
1
)
ax+by=1(gcd(a,b)=1)
ax+by=1(gcd(a,b)=1)的整数特解
设 r = a % b = a − a b r=a\%b=a-\frac{a}{b} r=a%b=a−ba,有:
a x + b y = 1 ⇒ ( r + a b ⋅ b ) x + b y = 1 ⇒ b ( a b ⋅ x + y ) + r x = 1 ax+by=1\Rightarrow(r+\frac{a}b\cdot{b})x+by=1\Rightarrow{b(\frac{a}{b}\cdot{x}+y)+rx=1} ax+by=1⇒(r+ba⋅b)x+by=1⇒b(ba⋅x+y)+rx=1令
{ x ′ = a b ⋅ x + y y ′ = x \begin{cases}x^{\prime}=\frac{a}{b}\cdot{x}+y\\y^{\prime}=x\end{cases} {x′=ba⋅x+yy′=x有:
{ x = y ′ y = x ′ − a b y ′ \begin{cases}x=y^{\prime}\\y=x^{\prime}-\frac{a}{b}y^{\prime}\end{cases} {x=y′y=x′−bay′关于 b 与 r 互质的事实已在上最大公约数算法原理中证实,于是可以发现这个问题被表达为另一个同类型的子问题,这可以写一个递归,结束条件为:
r = 0 时 { x = 1 y = 0 r=0时\begin{cases} x=1\\y=0\end{cases} r=0时{x=1y=0
代码实现(顺带求gcd)
int gcd(int a,int b,int&x,int&y){
if(!b){
x=1;y=0;
return a;
}
int ans = gcd(b,a%b,y,x);//a%b就是r,y和x换位是为了直接让x=y`而y=x`,之后再减一个a/b*x即可
y-=a/b*x;
return ans;
}
- 其他二元一次方程及其整数解
可以发现上面算法其实与方程等号右边是否为1无关,事实上,它同样适用于任意的:
a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)两边同除 g c d ( a , b ) gcd(a,b) gcd(a,b)即可变回原来分析的方程,而保持解 ( x , y ) (x,y) (x,y)不变。
而对于任意方程:
a x + b y = c ax+by=c ax+by=c其有整数解当且仅当 c % g c d ( a , b ) = 0 c\%gcd(a,b)=0 c%gcd(a,b)=0时(证明略),很明显,其解为:
{ x = k ⋅ x 0 y = k ⋅ y 0 { ( x 0 , y 0 ) ∣ a x 0 + b y 0 = g c d ( a , b ) } ( k = c g c d ( a , b ) ) \begin{cases}x=k\cdot{x_{0}}\\y=k\cdot{y_{0}}\end{cases}\{(x_{0},y_{0})|ax_{0}+by_{0}=gcd(a,b)\}(k=\frac{c}{gcd(a,b)}) {x=k⋅x0y=k⋅y0{(x0,y0)∣ax0+by0=gcd(a,b)}(k=gcd(a,b)c) - 求二元一次方程的最小非负整数解
先对于 a x + b y = 1 ( g c d ( a , b ) = 1 ) ax+by=1(gcd(a,b)=1) ax+by=1(gcd(a,b)=1),用扩展欧几里德算法得到的解为 ( x 0 , y 0 ) (x_{0},y_{0}) (x0,y0),那么显然最小正整数解 x x x 可以表示为:
x = { x 0 % b + b , x ≤ 0 x 0 % b , x > 0 = ( x 0 % b + b ) % b x=\begin{cases}x_{0}\%b+b,x\leq0\\x_{0}\%b,x>0\end{cases}=(x_{0}\%b+b)\%b x={x0%b+b,x≤0x0%b,x>0=(x0%b+b)%b类似的对于 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b):
x = ( x 0 % q + q ) % q ( q = b g c d ( a , b ) ) x=(x_{0}\%q+q)\%q~(q=\frac{b}{gcd(a,b)}) x=(x0%q+q)%q (q=gcd(a,b)b)
而对于 a x + b y = c ( c % g c d ( a , b ) = 0 ) ax+by=c(c\%gcd(a,b)=0) ax+by=c(c%gcd(a,b)=0):
x = ( x 1 % q + q ) % q ( q = b g c d ( a , b ) ) ( x 1 = x 0 ⋅ c g c d ( a , b ) ) x=(x_{1}\%q+q)\%q~(q=\frac{b}{gcd(a,b)})(x_{1}=x_{0}\cdot\frac{c}{gcd(a,b)}) x=(x1%q+q)%q (q=gcd(a,b)b)(x1=x0⋅gcd(a,b)c)相应的 y y y带入原方程即可解得。