1. 理论依据
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)
证明方法与辗转相除法类似。
2. 应用
辗转相除法可以用来求若干个形如 ( p q ) r i (\frac pq)^{r_i} (qp)ri的数的最大公约数,其中:
- p q \frac pq qp不可以再表示为次幂的形式
- p p p、 q q q、 r i r_i ri均为正整数
3. 算法推导
我们要求若干个形如
(
p
q
)
r
i
(\frac pq)^{r_i}
(qp)ri的数的最大公约数,即求指数的最大公约数,即:
f
(
p
x
,
p
y
)
=
p
(
x
,
y
)
=
p
(
y
,
x
−
y
)
=
f
(
p
y
,
p
(
x
−
y
)
)
=
f
(
p
y
,
p
x
p
y
)
f(p^x, p^y) = p^{(x, y)}=p^{(y, x-y)}=f(p^y,p^{(x-y)})=f(p^y, \frac {p^x}{p^y})
f(px,py)=p(x,y)=p(y,x−y)=f(py,p(x−y))=f(py,pypx)
ps:
- 第二个等号由更相减损术得到
- x 要大于 y
代码如下:
int gcd_sub(int a, int b){
if(a < b) swap(a, b);
if(b == 1) return a; // 此时p^y = 1即y = 0
// 由于0和任何正整数r的最大公约数都是r,所以此时应返回p^r,即a
return gcd_sub(b, a / b);
}
4. 与辗转相减法的区别
时间复杂度 | |
---|---|
辗转相除法 | O(logn) |
辗转相减法 | O(n) |
所以我们在求gcd的时候,通常还是用辗转相除法的。不过在上述这种特殊情况用辗转相除法不太方便的时候,我们采用辗转相减法。