又名百度谷歌算法、拔山盖世算法 其实叫大步小步算法。
给定 求满足 的最小自然数 。
普通的 BSGS 假设了 为质数。
令 ,其中 ,注意是向上取整。那么原式为
移项得到
枚举 ,预处理出 并在一个桶中记录。
枚举 ,找到第一个满足 。
此时 即为答案。
证明略,我不会。可以发现 BSGS 复杂度为
,如果用 map 当桶的话加个
。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
#define int long long
inline int read() {int x = 0, f = 0; char ch = 0;while (!isdigit(ch)) f |= ch == '-', ch = getchar();while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();return f ? -x : x;
}
//a^x = b (mod p)
map<int, int> mp;
int ksm(int a, int k, int p) {int res = 1;while (k) {if (k & 1) res = res * a % p;a = a * a % p;k >>= 1;}return res % p;
}
int BSGS(int a, int b, int p){int m = ceil(sqrt(p));for (int i = 1; i <= m; i++) mp[ksm(a, i, p) * b % p] = i;int t = ksm(a, m, p), ans = 1;for (int i = 1; i <= m; i++) {ans = ans * t % p;if (mp[ans]) return ((i * m - mp[ans]) % p + p) % p;}return -1;
}
signed main() {int p = read(), a = read(), b = read();int ans = BSGS(a, b, p);if (ans == -1) puts("no solution");else printf("%lld\n", ans);return 0;
}