更相减损术(辗转相减法)
更相减损术:已知两数\(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)\)次。