並不重要的前言
最近學習了一些數論知識,但是自己都不懂自己到底學了些什么qwq,在這里把知識一並總結起來。
也不是很難的gcd和lcm
顯而易見的結論:
為什么呢?
根據唯一分解定理:
a和b都可被分解為素因子的乘積,形如:
則顯而易見的有一下結論:
相乘,得:
得證
幾種求gcd的算法
-
- 歐幾里得算法(輾轉相除法)
- 輾轉相減法(優化:stein_gcd)
歐幾里得算法
基於事實:
實現:
1 int gcd(int a, int b){ 2 return (b == 0) ? a : gcd( b , a % b) ; 3 }
簡短而容易實現和記憶,非常優美
但是可能會被斐波那契數列卡住,證明或者原因鴿了回頭再寫
stein_gcd算法
stein_gcd本質上是對更相減損術的優化,下面進行簡單的介紹:
- 若a,b都是偶數,則計算gcd(a/2,b/2)*2; ————>因為都含有2的因數,所以同時除以2后gcd(a,b)變為原來的1/2,再乘回去
- 若a是偶數,b是奇數,則計算gcd(a/2,b); ————>因為只有一個數含有2作為因數,所以除以2后gcd(a,b)不變
- 若a是奇數,b是偶數,則計算gcd(a,b/2); ————>同2.
- 若a是奇數,b是奇數,則計算gcd(abs(x-y),min(x,y)); ————>通過相減,使其變成偶數,原理參見更相減損術其實是我懶得寫
實現:
int stein_gcd(int x,int y){ if(x==0) return y; if(y==0) return x; if(x%2==0&&y%2==0) return stein_gcd(x>>1,x>>1)*2; else if(x%2 ==0) return stein_gcd(x>>1,y); else if(y%2==0) return stein_gcd(x,y>>1); else return stein_gcd(abs(x-y),min(x,y)); }
講到這里,大概本期就結束了,至於沒涉及到的,就是鴿了下一期的事情了
至於下一次什么時候填坑,已經在做了逃