已發布·持續改進
Algorithm
最大公因數與最小公倍數、模運算與模反元素、快速冪、埃拉托斯特尼篩法和 nCr mod p:演算法中常用的數論工具。
數論研究整數的性質,尤其是整除與餘數。在演算法中,它代表用歐幾里得演算法求最大公因數與最小公倍數、用模運算處理巨大的數值,並用擴展歐幾里得演算法或費馬小定理求模反元素。再加上快速冪、埃拉托斯特尼篩法、質因數分解,以及模質數下的組合數計算,就構成一套完整的工具箱。
這些工具在程式面試與程式競賽中經常出現,典型的說法是「輸出答案除以 10^9 + 7 的餘數」。在實際系統中,它們是 RSA、Diffie-Hellman 等公開金鑰密碼、雜湊函式、亂數產生器與檢查碼的基礎。大多數演算法的執行時間是對數級或接近線性,理解原理之後,樸素方法永遠算不完的計算可以在幾毫秒內完成。
建議先手動推演模運算的性質與歐幾里得演算法,再親自實作快速冪與篩法。接著學習模反元素與 nCr mod p;如果使用 C++ 或 Java,務必練習處理乘法溢位與負數取餘。同時熟悉 Python 的 pow(a, e, m)、math.gcd 等標準函式也很有幫助。
反覆套用 gcd(a, b) = gcd(b, a mod b),在 O(log n) 時間內求出最大公因數;擴展版本還能同時求出滿足 ax + by = gcd(a, b) 的係數。
加、減、乘運算都會保留餘數,因此每一步都取餘以控制數值大小;除法則改為乘上模反元素。
把指數看成二進位,不斷將底數平方並依位元相乘,用約 log e 次而不是 e 次乘法算出 a^e mod m。
從 i × i 開始劃掉每個質數的倍數,在 O(n log log n) 內找出 n 以內的所有質數;搭配最小質因數表還能快速分解質因數。
gcd 以歐幾里得演算法求最大公因數,最小公倍數則由 a // gcd(a, b) * b 得到。mod_pow 是快速冪:逐一檢查指數的位元,反覆平方與相乘;當模數是質數 p 時,a^(p-2) 就是 a 的模反元素。sieve 以埃拉托斯特尼篩法列出 30 以內的所有質數。將檔案存好後執行 python number_theory.py 即可。
number_theory.py
import math
def gcd(a: int, b: int) -> int:
while b:
a, b = b, a % b
return a
def mod_pow(base: int, exp: int, mod: int) -> int:
result, base = 1 % mod, base % mod
while exp > 0:
if exp & 1:
result = result * base % mod
base = base * base % mod
exp >>= 1
return result
def sieve(n: int) -> list[int]:
is_prime = [False, False] + [True] * (n - 1)
for i in range(2, math.isqrt(n) + 1):
if is_prime[i]:
for j in range(i * i, n + 1, i):
is_prime[j] = False
return [i for i, p in enumerate(is_prime) if p]
MOD = 10**9 + 7
print(gcd(84, 36), 84 // gcd(84, 36) * 36) # 12 252
print(mod_pow(3, 200, 13)) # 9
print(mod_pow(3, MOD - 2, MOD)) # 333333336, the inverse of 3
print(sieve(30)) # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
python number_theory.py共六章,帶你從安裝一步步認識 數學與數論 的核心概念。
在這裡提問、分享經驗,交流關於 數學與數論 的看法。
還沒有討論。來發起第一則吧。
0 則留言
登入 · 登入後即可留言。
來留下第一則留言吧。