BSGS(Baby-Step Giant-Step)算法
BSGS (Baby-Step Giant-Step) 算法
作用:求满足 \(a^t \equiv b \ (mod \ p)\) 的最小的正整数 \(t\),保证 \(a\) 和 \(p\) 互质。
方法:由欧拉定理:
\[a^{\phi(p)} \equiv 1 \ (mod \ p)
\]
有:
\[ a^t \equiv a^{x \ mod \ \phi(p)} \ (mod \ p) \ \ \ \ \ \ t \in [0, \phi(p) - 1]
\]
这里为了方便我们将 \(t\) 的右端点取为 \(p\) ,之后采用分块思想,将 \(t\) 的取值分为 \(k\) 块,其中 \(k = \lceil \sqrt{p} \rceil = \lfloor \sqrt{p} \rfloor + 1\)
则 \(t\) 可以用 \(k\) 进行表示:
\[t = kx - y \ \ \ \ \ x \in [1,k] \ \ \ \ \ y \in [0, k - 1]
\]
此时 \(t\) 的取值范围是 \([1, k^2]\),因此该表示包含了 \(t\) 的所有可能取值。
这里 \(x\) 从 1 开始,防止 \(t\) 出现负数。
设 \(t = kx - y\) 而不是 \(t = kx + y\) 的原因是:
\[a^t = a^{kx-y} \equiv b \ (mod \ p) \\
\Rightarrow a^{kx} \equiv ba^{y} \ (mod \ p)
\]
这里就不需要先计算逆元了,简化代码。
故该问题转化为:对于某一 \(x\),判断是否存在 \(y\),使得 \(x,y\) 满足 \(a^{kx} \equiv ba^{y} \ (mod \ p)\)
显然该问题可以用哈希表解决,即:
- 将 \(b * a^y \ (mod \ p)\) 用哈希表进行存储
- 存储 \(b * a^y \ (mod \ p)\) 的值对应哪个 \(y\),如果有多个 \(y\),取最大的 \(y\)(因为这样的 \(t\) 会更小)
最后对于所有满足条件的 \(x, y\),取最小的 \(t\) 即可,由于 \(x\) 从 1 开始取,因此还需要特判一下 \(t=0\) 的情况,该算法的时间复杂度为 \(O(\sqrt{p})\)
模板题:BSGS
AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<unordered_map>
using namespace std;
using ll = long long;
int a, p, b;
ll bsgs(int a, int p, int b) {
if(1 % p == b % p) return 0;
unordered_map<int, int> ump;
int k = sqrt(p) + 1;
//求b*a^ymodp
for (int i = 0, j = b % p; i < k; i ++) {
ump[j] = i;
j = (ll)j * a % p;
}
//求a^k
int ak = 1;
for (int i = 1; i <= k; i ++) {
ak = (ll)ak * a % p;
}
//求a^k^x
for (int i = 1, j = ak % p; i <= k; i ++) {
if(ump.count(j)) return (ll)k * i - ump[j];
j = (ll)j * ak % p;
}
return -1;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> a >> p >> b, a || p || b) {
ll res = bsgs(a, p, b);
if(res == -1) {
cout << "No Solution" << '\n';
continue;
}
cout << res << '\n';
}
return 0;
}
扩展BSGS
将上述题意改为:求满足 \(a^t \equiv b \ (mod \ p)\) 的最小的正整数 \(t\),不保证 \(a\) 和 \(p\) 互质。
分类讨论:
- 当 \(t = 0\) 时特判即可
- 当 \(t \geq 1\) 时,设 \(gcd(a,p) = d\):
- 若 \(d = 1\) 采用朴素BSGS处理
- 若 \(d > 1\) 则对原式进行处理:\[ a^t \equiv b \ (mod \ p) \\ \Rightarrow a^t + kp = b \\ \Rightarrow \frac{a}{d} \cdot a^{t-1} + k \cdot \frac{p}{d} = \frac{b}{d} \\ \Rightarrow \frac{a}{d} \cdot a^{t-1} \equiv \frac{b}{d} \ (mod \ p) \\ ∵ gcd(\frac{a}{d}, \frac{p}{d}) = 1 \\ ∴ a^{t-1} \equiv \frac{b}{d} \cdot (\frac{a}{d})^{-1} \ (mod \ \frac{p}{d}) \]
\[a^{t^{'}} \equiv b^{'} \ (mod \ p^{'}) \]若 \(a\) 与 \(p^{'}\) 互质,则转化为朴素BSGS,否则根据上述转化进行递归,直到其互质为止,由于 \(p\) 的因子 \(d\) 的个数有限,因此只需递归有限次即可停止。
模板题:扩展BSGS
AC代码:

浙公网安备 33010602011771号