BSGS

基础篇

  • BSGS(baby-step giant-step),即大步小步算法。常用于求解离散对数问题。形象化的说,该算法可以在\(O(\sqrt p)\)的时间内求解\(a^x \equiv b(\mod p)\)(即求解高次同余方程)
  • 其中\(a \perp b\)。方程的解\(x\)满足\(0\le x < p\)。(不要求\(p\)为素数)
  • 算法描述
  • \(x=A\lceil {\sqrt p} \rceil-B\)其中\(0 \le {A,B} \le {\lceil {\sqrt p} \rceil}\),则有\(a^{A\lceil{\sqrt p} \rceil-B}\equiv b(\mod p)\),变换,则有\(a^{A\lceil {\sqrt p} \rceil}\equiv b(\mod p)\)
    我们已知\(a,b\),所以我们可以先算出等式右边的\(ba^B\)的所有取值,枚举B用hash/map存下来,然后逐一计算\(a^{A\lceil {\sqrt p}\rceil}\),枚举\(A\)寻找是否有与之相等的\(ba^B\),从而我们可以得到所有的\(x\),\(x=A\lceil {\sqrt p}\rceil-B\)
    注意到\(A\),\(B\)均小于\(\sqrt p\),所以时间复杂度为\(O(\sqrt p)\),用map则多一个log
ll BSGS(ll a,ll b,ll p){
    map<int,int>hash;
    ll t=sqrt(p)+1;
    for(int i=0;i<t;i++){
        ll val=b*qpow(a,i,p);
        hash[val]=i;
    }
    a=qpow(a,t,p);
    if(a==0)return b==0?1:-1;
    for(int i=0;i<=t;i++){
        ll val=qpow(a,i,p);
        int j=hash.find(val)==hash.end()?-1:hash[val];
        if(j>=0&&i*t-j>=0)return i*t-j;
    }
    return -1;
}
posted @ 2021-07-14 17:19  无琛  阅读(273)  评论(0)    收藏  举报