大步小步算法

BSGS

假设对于给定的a,b,质数p,我们要求满足\(a^x=b(mod\;p)\)的所有x。

一个常规的想法是直接枚举[1,p-1],因为\(a^{p-1}=1(mod\;p)\),超过p就开始循环了,但是在p的范围较大时不可行。

我们先求出\([1,\sqrt[2]{x}]\)的答案,然后对于更大的,直接乘出根号的逆元,用map判断是否存在这个解,复杂度为\(O(\sqrt[2]{n}\;logn)\)

代码:

int qpow(int x,int k)
{
 if (k==0) return 1;
 int temp=qpow(x,k>>1);temp=(temp*temp)%p;
 if (k&1) return (temp*x)%p;
}

void init()
{
 for (B=1;B*B<=p;++B);
 k=1;
 rep(i,1,B)
 {
  k=(k*a)%p,M[k]=i;
  if (k==b) {ans=i;return;}
 }
 Rev=qpow(k,p-2);
}

int BSGS()
{
 k=b;
 for (int i=B*2;i<p;i+=B)
 {
  k=(Rev*k)%p;
  if (M[k]) return M[k]+i-B;
 }
 return -1;
}
posted @ 2017-04-20 21:25  Krew  阅读(296)  评论(0)    收藏  举报