1.離散對數
就是在模 \(p\) 意義下求出 \(\log_ab\)。等價於求出方程 \(a^x \equiv b \pmod m\) 的解。其中的 \(x\) 就是 \(\log_ab\)。
當 \(a \perp p\) 時,BSGS 演算法可以求解出上面那個方程的解。具體的計算過程如下:
我們設塊長 \(M\),並且 \(x = AM - B\),那麼 \(a^{AM} \equiv ba^{B} \pmod m\)。那麼我們可以列舉所有可能的取值然後用一個雜湊表或者 map 判斷是否相等即可。時間複雜度為 \(O(\max(A,B))\)。我們知道 \(0 \le B < M,0 \le A \le \lceil \frac{p-1}{M} \rceil\),那麼很明顯當 \(M\) 取到 \(\lceil \sqrt p \rceil\) 時,複雜度最小,為 \(\mathrm O(\sqrt p)\)。
但是如果沒有 \(a \perp p\),我們就需要使用 exBSGS 演算法。
此時我們令 \(d = \gcd(a,p)\),然後方程兩邊同時除以 \(d\),那麼方程變為 \(\dfrac{a}{d}a ^ {x - 1} \equiv \dfrac{b} {d}\pmod{\dfrac{p}{d}}\)。
此時我們注意到 \(\dfrac{a}{d} \perp \dfrac{p}{d}\),那麼前面的數存在在後面的數的意義下的逆元,那麼就有 \(a^{x-1} \equiv \dfrac{b}{d} \times (\dfrac{a}{d})^-1 \pmod{\dfrac{p}{d}}\)。如果 \(a\) 和 \(\dfrac{p}{\gcd(a,p)}\) 不互質,那麼我們就重複上面的操作使得 \(\dfrac{p}{\gcd(a,p)}\) 和 \(a\) 互質後再用 BSGS 即可。
注意最後求出的解還需要加上操作次數。
2.階
我們定義 \(\delta_p(a)\) 為最小滿足同餘方程 \(a^n \equiv 1\pmod p\) 的 \(n\),讀作 \(a\) 模 \(m\) 的階。
接下來是幾個重要的性質。
\(\text{Lemma 1}\):\(a^1 \cdots \cdots a^{\delta_m(a)}\) 模 \(m\) 所得的餘數互不相同。
\(\text{Proof 1}\):假若有兩個數 \(i,j\) 滿足 \(\delta_m(a)\) 使得 \(a^i \equiv a^j\pmod m\),那麼必定有 \(a^{|i-j|}\equiv 1 \pmod m\)。這與階的最小性矛盾,故原命題成立。
\(\text{Lemma 2}\):對於所有的 \(a^n \equiv 1 \pmod m\),必定有 \(n \mid \delta_m(a)\)。
\(\text{Proof 2}\):我們還是考慮反證法。我們設 \(n = \delta_m(a) \times q + r\),其中 \(0 < r < \delta_m(a)\)。那麼 \(a^r \equiv a^r \times (a^{\delta_m(a)})^q \equiv a^n \equiv 1 \pmod m\),這與階的最小性矛盾,那麼原命題成立。
\(\text{Lemma 3}\):\(\delta_m(g^k) = \frac{\delta_m(g)}{\gcd(\delta_m(g),k)}\)。
\(\text{Proof 3}\):我們發現 \(g^{k\delta_m(g^k)} \equiv (g^k)^{\delta_m(g^k)} \equiv 1 \pmod m\)。那麼就有 \(\delta_m(g) \mid k \times \delta_m(g^k)\),所以就有 \(\frac{\delta_m(g)}{\gcd(\delta_m(g),k)} \mid \delta_m(g^k)\)。同時我們知道 \((g^k)^{\frac{\delta_m(g^k)}{\gcd(\delta_m(g),k)}} \equiv (g^{\delta_m(g)})^{\frac{k}{\gcd(\delta_m(g),k)}}\),那麼就有 \(\delta_m(g^k) \mid \frac{\delta_m(g)}{\gcd(\delta_m(g),k)}\)。那麼原命題成立。
至於求法,我們可以世界使用 BSGS 來求出階。
3.原根
注意是原根不是原神。
假如 \(\gcd(g,m) = 1\) 並且 \(\delta_m(g) = \varphi(m)\),那麼我們稱 \(g\) 為 \(m\) 的原根。
原根個數定理:假如 \(m\) 有原根,則 \(m\) 的原根個數為 \(\varphi(\varphi(m))\)。
若 \(m\) 有原根 \(g\),那麼就有 \(\delta_m(g) = \frac{\delta_m{g}}{\gcd(\delta_m{g},k)} = \frac{\varphi(g)}{\gcd(\varphi(g),k)}\)。如果 \(\gcd(k,\varphi(m)) = 1\),那麼 \(\delta_m{g^k}\) 也是 \(m\) 的原根。由於我們知道在 \(1\) 到 \(\varphi(m)\) 之間和 \(\varphi(m)\) 互質的數有 \(\varphi(\varphi(m))\) 個,那麼原根的個數就是 \(\varphi(\varphi(m))\)。