BSGS
BSGS(baby step giant step)就是求同余方程
ax≡b(modp)
我们设 x=im−j ,将其带入式子可以得到
aim−j≡b(modp)
即 aim≡b∗aj(modp)
我们可以计算 b∗ajmodp (i=0 to m)的值(快速幂) 将其放入map中 map[b∗ajmodp]=j
之后再枚举a的im次mod p的值,如果发现再map有对应解
ans=m∗i−map[aimmodp]
可以证明,当 m=p‾‾√ 最快。
为什么 x=im−j ,即x的最大值不超过p.
有公式即 ak%p−1≡ak(modp) (当a与p互质),通过小费马证得。
k 可以看成 k−m(p−1) 于是上面的式子变成了
ak(a(p−1))m≡ak(modp)
由于小费马, ap−1≡1(modp) ,可以得到
ak1m≡ak(modp)
这样就确保了x比p小。
LL BSGS(LL y,LL z,LL p)
{
map<LL,LL> ma;
LL m=sqrt(p),tmp=0;
ma.clear();
if(y%p==0&&z==0) return 1;
if(y%p==0&&z!=0) return -1;
for(int i=0;i<=m;i++)
{
if(!i) {tmp=z%p;ma[tmp]=i;continue;}
tmp=(tmp*y)%p;
ma[tmp]=i;
}
tmp=1;LL t=power(y,m,p);
for(int i=1;i*i<=p;i++)
{
tmp=(tmp*t)%p;
if(ma[tmp])
{
LL ans=i*m-ma[tmp];
return ans;
}
}
return -1;
}