BSGS
BSGS
bsgs用于求指数方程\(a^x \equiv b \pmod m\)的解
然后令\(x = q * t - r\),得到\(b*a^r = a^{qt}\)
然后就枚举 :\(q \in {(0,m/t+1)} , r \in (0,t-1)\)
预处理\(a^{qt}\),枚举\(r\)判断\(ba^r\)是否有\(a^{qt}\)与其相等(map)
int m=sqrt(p)+1;Hash.Clear();
for(RG int i=0,t=z;i<m;++i,t=1ll*t*y%p)Hash.Insert(t,i);
for(RG int i=1,tt=fpow(y,m,p),t=tt;i<=m+1;++i,t=1ll*t*tt%p)
{
int k=Hash.Query(t);if(k==-1)continue;
printf("%d\n",i*m-k);return;
}
EXBSGS
\(a^x \equiv b \pmod m\)
\(a*a^{x-1} \equiv b \pmod m\)
\(d=(a,m)\)
\(\frac{a}{d}*a^{x-1} \equiv \frac{b}{d} \pmod {\frac{m}{d}}\),如果d不能整除b则无解
\(a^{x-1} \equiv \frac{b}{d}*(\frac{a}{d})^{-1} \pmod {\frac{m}{d}}\)
然后递归,gcd(a,m)=1为质数就BSGS,快乐得很
int exbsgs(int a,int b,int p)
{
if (b==1||p==1)return 0; //特殊情况,x=0时最小解
int g=gcd(a,p),k=0,na=1;
while (g>1)
{
if (b%g!=0)return -1; //无法整除则无解
k++;b/=g;p/=g;na=na*(a/g)%p;
if (na==b)return k; //na=b说明前面的a的次数为0,只需要返回k
g=gcd(a,p);
}
int f=bsgs(a,b*inv(na,p)%p,p);
if (f==-1)return -1;
return f+k;
}