1. 程式人生 > 其它 >離散對數&BSGS學習筆記

離散對數&BSGS學習筆記

離散對數定義

\(k\) 使得 \(a^k \equiv n \pmod p\) ,稱 \(n\) 在模 \(p\) 意義下以 \(a\) 為底的對數是 \(k\)

如何求離散對數

BSGS(Baby Step,Giant Step)大步小步演算法可以求離散對數,它的思想是分塊思想。

首先要滿足 \(a \perp p\) ,因為在後面會需要把兩邊同時除以 \(a\) 的冪,所以需要 \(a \perp p\)

考慮樸素的演算法,我們可以列舉 \(k\) ,找到使得 \(a^k \equiv n \pmod p\)\(k\) ,時間複雜度 \(O(p)\) ,但 \(p\) 一般都很大,所以考慮優化。

我們可以把 \(1\)\(p\) 進行分塊,然後先一塊一塊地走,然後快到答案是再一個一個走,如果塊長是 \(m\) ,時間複雜度為 \(O(\max\{m,p/m\})\) ,不難發現,當 \(m = \sqrt n\) 時,時間複雜度是最優的 \(O(\sqrt p)\) ,這就是 BSGS 的思想,可以從名字裡看出。

具體實現:設一大步步長為 \(t\) ,大步步數為 \(i\) ,則 \(k=i \times t - r\) ,其中 \(r\) 是往回走小步的步數,把它代入上面的式子中可得:

\[a^{i\times t - r} \equiv n \pmod p \] \[a^{i\times t} \times a^{-r} \equiv n \pmod p \] \[a^{i \times t} \equiv n \times a^{r} \pmod p \]

我們可以列舉大步步數(大步步長是確定的),然後每次判斷有沒有 \(r\)

滿足 \(a^{i \times t} \equiv n \times a^{r} \pmod p\), 但是如果列舉 \(r\) 就還是 \(O(p)\) 的,但 $1 \le r < t $ ,所以我們可以預處理出 \(n \times a^{0}\)\(n \times a^{1}\) 一直到 \(n \times a^{t}\) , 然後用 map 存下來,以他們對 \(p\) 的餘數作為索引,\(a^{r}\) 中的 \(r\) 作為值,然後列舉大步步數,每次 \(O(1)\) 判斷,這樣時間複雜度就是 \(O(\sqrt p \log p)\) ,其中 \(\log p\)
是 map 的時間複雜度。這就是 BSGS 。

code

int fpow(int a, int b, int p) {
	if (b == 1)
		return a;
	int ans = fpow(a, b / 2, p);
	ans = (1ll * ans * ans) % p;
	if (b % 2 == 1)
		ans = (1ll * ans * a) % p;
	return ans; 
}
int stp, r;
int nbr[50000], t;
map<int, int> mp;
int BSGS(int p, int b, int n) {
	stp = sqrt(p), t = fpow(b, stp, p), nbr[0] = n % p;
	for (int i = 1; i < stp; i++) { //注意這裡是小於,不然 n=1 時會掛
	    nbr[i] = (1ll * nbr[i - 1] * b) % p;
	    mp[nbr[i]] = i;
	}
	for (int i = 1, lt = t; 1ll * i * stp - stp <= p; i++, lt = (1ll * lt * t) % p)
		if (mp[lt] > 0) 
		    return 1ll * i * stp - mp[lt];
	return -1;
}

BSGS 求階

\(a \perp p\) 時,最小的正整數 \(k\) 滿足 \(a^k \equiv 1\pmod p\) ,則稱 \(k\)\(n\)\(p\) 的階,記作 \(\delta_p(a)\)\(Ord_p(a)\)

一個數的階就可以用 BSGS 來求,方法同上面一樣。

BSGS 的一些題目

P1082 [NOIP2012 提高組] 同餘方程

題意:求最小的正整數 \(x\) 滿足 \(ax \equiv 1 \pmod p\)

思路

這題的題解貌似一篇 BSGS 的都沒有~~

BSGS 不只是可以求離散對數,這道題也可以做。我們設一大步步長為 \(t\) ,大步步數為 \(i\) ,則 \(x=i \times t - r\) ,其中 \(r\) 是往回走小步的步數,把它代入上面的式子中可得:

\[a\times(i \times t-r) \equiv 1 \pmod p \] \[a \times i \times t \equiv a \times r + 1 \pmod p \]

所以我們就可以提前預處理出所有 \(1 \le r \le \sqrt p\)\(ar+1\) 的值,然後列舉大步,每次 \(O(1)\) 判斷即可, 時間複雜度 \(O(\sqrt p \log p)\)

P2485 [SDOI2011]計算器

題意:回答三種詢問,分別是:

  1. \(y^z \mod p\) 的值。

  2. 滿足 \(xy \equiv z\pmod p\) 的最小整數 \(x\)

  3. 滿足 \(y^x \equiv z \pmod p\) 的最小整數 \(x\)

思路

操作一:直接快速冪即可。

操作二:BSGS 直接求,和上一道題幾乎一樣,就是把 \(ar+1\) 改成 \(ar+z\) 即可。

操作三:BSGS 原封不動就可以了。

時間複雜度:\(O(\sqrt p \log p)\)\(O(\log z)\)