\(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;
}
//}}}
02-13 06:26