bsgs算法用来解决有关A^x ≡ B (mod C)的方程, 求x
把x看成 i*m-j,上面的式子就可以变成A^(i * m - j) ≡ B (mod C) => A^(i * m) ≡ B * A^j (mod C)
具体解释看这个:https://blog.csdn.net/clover_hxy/article/details/50683832
这个博客是用map写的,我用map写完交这个题的时候刚好卡过去,大概是用4700ms左右
之后又把map改成哈希只用了16ms!!!!
map和哈希的时间差300倍!!!!
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
struct Thash{//相当于map
static const int MOD=233333;
static const int MAXN=1e6+5;
int tot,head[MOD+100],next[MAXN],h[MAXN],val[MAXN];
inline void clear(){tot=0;memset(head,0,sizeof head);}
inline void insert(int H,int VAL){//map<H, VAL>;
for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H){val[i]=VAL;return ;}
h[++tot]=H;val[tot]=VAL;next[tot]=head[H%MOD];head[H%MOD]=tot;
}
inline int get(int H){//map[H];
for(int i=head[H%MOD];i;i=next[i]) if(h[i]==H) return val[i];
return 0;
}
}M;
ll qpow(ll a, ll b, ll mod) {ll ans = 1;while (b) {if (b % 2) ans = ans * a % mod;a = a * a % mod;b /= 2;}return ans;}
ll bsgs(ll A, ll B, ll C) {//A^x = B (mod C) => A^(i * m - j) = B (mod C) => A^(i * m) = B * A^j (mod C)
if (A % C == 0)
return -1;
if(B % C == 0)
return 1;
M.clear();
ll m = ceil(sqrt((double)C));
ll temp = B % C;
for (int i = 0; i <= m; i++) {//先暴力 B * A^j 把 j 存到mp里
M.insert(temp, i);
temp = temp * A % C;
}
ll t = qpow(A, m, C);
temp = 1;
for (int i = 1; i <= m; i++) {
temp = temp * t % C;
int u = M.get(temp);
if (u) {
ll ans = (i * m % C - u % C + C) % C;
return ans;
}
}
return -1;
}//-1代表无解
int main() {
ll A ,B, C;
while (scanf("%lld%lld%lld", &C, &A, &B) != EOF) {
ll ans = bsgs(A, B, C);
if (ans != -1)
printf("%lld\n", ans);
else
printf("no solution\n");
}
return 0;
}