輾轉相除法(歐幾里得演算法)(gcd)模板及其原理

GETOVERMIND發表於2020-10-21

下面給出學長教的模板:

typedef long long ll;
ll gcd(ll a,ll b)
{
	return b==0?a:gcd(b,a%b);
}

其計算原理依賴於以下定理:
定理:兩個整數的最大公約數等於其中較小的那個數(也就是除數)和兩數相除餘數的最大公約數。最大公約數(Greatest Common Divisor)縮寫為GCD。

對於程式碼的解釋:
以除數和餘數反覆做除法運算,當餘數為 0 時,取當前算式除數為最大公約數。這一操作可以利用遞迴實現。

以下是對上面定理的證明,摘自百度百科link
證法一
a可以表示成a = kb + r(a,b,k,r皆為正整數,且r<b),則r = a mod b
假設d是a,b的一個公約數,記作d|a,d|b,即a和b都可以被d整除。
而r = a - kb,兩邊同時除以d,r/d=a/d-kb/d=m,由等式右邊可知m為整數,因此d|r
因此d也是b,a mod b的公約數
假設d是b,a mod b的公約數, 則d|b,d|(a-k*b),k是一個整數。
進而d|a.因此d也是a,b的公約數
因此(a,b)和(b,a mod b)的公約數是一樣的,其最大公約數也必然相等,得證。
證法二
假設c = gcd(a,b),則存在m,n,使a = mc, b = nc;
令r = a mod b,即存在k,使r = a-kb = mc - knc = (m-kn)c;
故gcd(b,a mod b) = gcd(b,r) = gcd(nc,(m-kn)c) = gcd(n,m-kn)c;
則c為b與a mod b的公約數;
假設d = gcd(n,m-kn), 則存在x,y, 使n = xd, m-kn = yd; 故m = yd+kn = yd+kxd = (y+kx)d;
故有a = mc = (y+kx)dc, b = nc = xdc; 可得 gcd(a,b) = gcd((y+kx)dc,xdc) = dc;
由於gcd(a,b) = c, 故d = 1;
即gcd(n,m-kn) = 1, 故可得gcd(b,a mod b) = c;
故得證gcd(a,b) = gcd(b,a mod b).
注意:兩種方法是有區別的。

相關文章