这里介绍一种避开求逆元的BSGS(常数小
离散对数问题:给定求\(y,z,p,\)求 \(y^x \equiv z\) $(mod $ \(p)\)的最小整数解,不过下面谈的是简单BSGS,保证\(p\)为素数.
令$ m = \lceil\sqrt p\rceil$, \(x = im-j\)
则 \(y^{im-j} \equiv z\) $(mod $ \(p)\)
两边同乘\(y^j\)得:
\(y^{im} \equiv zy^j\) $(mod $ \(p)\)
m、y、z已知,因此先枚举右边\(zy^j,j \in [0,m-1]\).算出来的值放进map里。再接着枚举左边,\(y^{im},i \in [1,m]\),如果发现map里有与之对应的值,返回\(im-j\),即要求\(x\).最后若未返回则无解.
可以看出BSGS是确定了枚举上界\(\lceil\sqrt p\rceil\)的暴力枚举算法.
LL Qpow(LL a, LL b) {
LL ans = 1;
for(; b; b>>=1, a=a*a%p)
if(b & 1) ans = ans * a % p;
return ans;
}
LL BSGS(LL y, LL z) {
map<int, int> M;
LL m = ceil(sqrt(p + 0.5)), cj = z;
for(int j=0; j<m; j++) {
M[cj] = j;
cj = cj * y % p;
}
LL now = Qpow(y, m);
cj = 1;
for(int i=1; i<=m; i++) {
cj = cj * now % p;
if(M.count(cj)) return i*m - M[cj];
}
return -1;
}