BSGS 学习笔记
\(\text{Problem}\)
求解的问题:高次同余方程
\[A^x \equiv B \pmod C,\text{其中}(A,C)=1 \]\(\text{Algorithm}\)
令 \(m = \left \lceil \sqrt C \right \rceil\)
考虑 \(x = i \cdot m-j,i \in [1,m],j \in [0,m)\)
然后式子可化为 \(A^{i \cdot m} \equiv B \cdot A^j \pmod C\)
然后枚举 \(j\),考虑哈希存右边式子的值,用哈希表实现
再枚举 \(i\),计算左边式子,然后哈希表中查找,如果找到了,那么答案就是 \(i \cdot m - j\),\(j\) 要在哈希表中记录
时间复杂度为 \(O(\sqrt C)\)
\(\text{Code}\)
#include
#include
#define LL long long
using namespace std;
const int N = 1e6 + 700, mod = 1e6 + 7;
LL p, b, n;
struct hash_table{
int tot, h[N];
struct edge{
LL val;
int nxt, w;
}e[N];
inline hash_table(){tot = 0;}
inline void insert(LL s, int w)
{
LL t = s % mod;
e[++tot] = edge{s, h[t], w}, h[t] = tot;
}
inline int find(LL s)
{
LL t = s % mod;
for(int i = h[t]; i; i = e[i].nxt)
if (e[i].val == s) return e[i].w;
return -1;
}
}H;
int main()
{
scanf("%lld%lld%lld", &p, &b, &n);
LL m = ceil(sqrt(p)), BB = 1;
for(int i = 0; i < m; i++, BB = BB * b % p, n = n * b % p) H.insert(n, i);
LL B = BB;
for(int i = 1, j; i <= m; i++, B = B * BB % p)
if ((j = H.find(B)) != -1)
{
printf("%lld\n", m * i - j);
return 0;
}
printf("no solution");
}