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;
}
posted @ 2019-07-27 23:12  lcyfrog  阅读(240)  评论(2编辑  收藏  举报