( ext{Problem})
求解的问题:高次同余方程
[A^x equiv B pmod C, ext{其中}(A,C)=1
]
( ext{Algorithm})
令 (m = left lceil sqrt C
ight
ceil)
考虑 (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))
( ext{Code})
#include<cstdio>
#include<cmath>
#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
", m * i - j);
return 0;
}
printf("no solution");
}