更相减损术(辗转相减法)

发布时间 2024-01-01 09:20:30作者: CQWYB

更相减损术:已知两数\(a\)\(b\),求\(gcd(a,b)\)

不妨设\(a \geq b\),若\(a=b\),则\(gcd(a,b)=a=b\),否则对于所有\(\forall d|a,d|b\),可以证明\(d|a-b\)

证明\(d|a-b\)如下,设\(a=k_1\times d\)\(b=k_2 \times d\),因为\(a>b\),所以一定有\((k_1>k_2)\)。所以\(a-b=(k_1-k_2)\times d\),又因为\(k_1\neq k_2\),所以\(d|a-b\),故得证。

因此,\(a\)\(b\)所有公因数都是\(a-b\)\(b\)的公因数,即\(gcd(a,b)=gcd(b,a-b)\)

算法优化

如果\(a >> b\)(\(>>\)表示远大于),那么这个算法时间复杂度是\(O(|a|)\)的。

那考虑优化,若\(2|a,2|b\)\(gcd(a,b)=2\times gcd(\frac{a}{2},\frac{b}{2})\),否则若\(2|a,2\nmid b\)\(2|b\))同理,\(gcd(a,b)=\frac{a}{2},b\),再如果\(2 \nmid a,2 \nmid b\)时,那么一定\(2|a-b\),那么又回到\(2|a,2\nmid b\)的情况了,优化后的算法是\(O(log n)\)的。

证明如下,每次操作一定至少能将\(a\)\(b\)之一减半。否则\(2|a-b\),回到上一种情况,算法最多进行\(O(log n)\)次。