浅谈 BSGS 算法
先放个模板题的链接:P3846 [TJOI2007] 可爱的质数/【模板】BSGS
BSGS,即 Baby Step Giant Step,又称为大步小步算法,用来解决数论里的一些同余方程问题:已知
先解释一下这个最小的
但是,我们发现欧拉函数无法满足我们的要求,它的时间复杂度是
实际上就是这个思考产生个 BSGS 算法。在介绍 BSGS 算法之前,先重申一下 BSGS 算法能解决的问题条件:
下面进入正题,将
把左右都乘一个
这样,我们就枚举所有 map 或者 hash 搞一下即可,时间复杂度
代码如下:
map<int,int> vis;
int qpow(int a,int b,int p){
if(!b)return 1%p;
int t=qpow(a,b>>1,p);
t=1LL*t*t%p;
if(b&1)t=1LL*t*a%p;
return t;
}
void solve(){
int a,b,p;
scanf("%d%d%d",&p,&a,&b);
int m=(int)ceil(sqrt(p)),cur=b;
for(int i=0;i<=m;i++){
vis[cur]=i;
cur=1LL*cur*a%p;
}
int mul=qpow(a,m,p);
cur=mul;
for(int i=1;i<=m;i++){
if(vis.count(cur)){
printf("%d\n",1LL*i*m-vis[cur]);
return;
}
cur=1LL*cur*mul%p;
}
printf("no solution\n");
}