\(Description\)
给定\(a,b,p\),求一个\(x\)使其满足\(a^x\equiv b\ \left(mod\ p\right)\)
\(BSGS\)
\(BSGS\)可以解决\(p\)为质数的情况
令 \(m=\lceil \sqrt p\rceil\)
令 \(x=i\cdot m-k\)
有 \(a^{i\cdot m-k} \equiv b\ (mod\ p)\)
两边同乘 \(a^k\) 得 \(a^{i\cdot m}\equiv b\cdot a^k\ (mod\ p)\)
我们先将右边的 \(b\cdot a^k\) 全部求出来存到一个表里,这样预处理时间复杂度为 \(\sqrt p\)
之后再枚举 \(i\) 到 \(\sqrt p\) ,看表里有没有 \(a^{i\cdot m}\ mod\ p\),有的话就有一组解
再反向求出\(x\)即可
\(EXBSGS\)
当\(p\)不是质数时
令 \(g=gcd(a,p)\)
有 \(a^{x-1}\cdot \dfrac{a}{g}\cdot g \equiv \dfrac{b}{g}\cdot g\ \left(mod\ \dfrac{p}{g}\cdot g\right)\)
把那个\(g\)除掉
\(a^{x-1}\cdot \dfrac{a}{g} \equiv \dfrac{b}{g}\ \left(mod\ \dfrac{p}{g} \right)\)
然后重复这个过程直到\(a,p\)互质
显然,在这个过程中如果\(p\)不能被\(b\)整除就无解
到最后会得到这样的方程
\(a^{x-i}\cdot c\equiv t\ \left(mod\ p\right)\)
\(c\)是由\(a\)的幂除以若干个因子得到的 \(c,t\)肯定互质
两边乘以\(c^{-1}\)(逆元)
\(a^{x-i}\equiv t\cdot c^{-1}\ \left(mod\ p\right)\)
用\(BSGS\)对\(x-i\)求解即可
最后记得加上\(i\)
\(Code\)
\(BSGS\)
ksm(a,b);//return a^b
gcd(a,b);//return gcd(a,b)
//{{{bsgs
int bsgs (int a,int b,int p)//return a^x ≡ b mod p 's x
{
a%=p;
if (!a&&!b) return 1;
if (!a) return -1;
int m=sqrt(p);
map <int,int> mp;//这里用的map 也可以自己打个哈希
int t=b%p;
mp[t]=0;
for (int i=1;i<=m;++i) mp[t=1ll*t*a%p]=i;
t=1;
int mi=ksm(a,m);
for (int i=1;1ll*i*i<=p+1;++i){
t=1ll*t*mi%p;
if (mp.count(t)) return ((1ll*i*m%p-mp[t])%p+p)%p;
}
return -1;
}
//}}}
\(EXBSGS\)
//{{{exbsgs
int exbsgs (int a,int b,int p)//a^x ≡ b mod p 's x
{
if (b==1) return 0;
int cnt=0,t=1;
for (int g=gcd(a,p);g!=1;g=gcd(a,p)){
if (b%g) return -1;
++cnt,b/=g,p/=g;
t=1ll*t*a/g%p;
if (b==t) return cnt;
}
int x=bsgs(a,1ll*ksm(t,p-2)*b%p,p);
if (x!=-1) x+=cnt;
return x;
}
//}}}