Baby-Step_Giant-Step(简称BSGS)及其扩展算法(简称Extended BSGS)用来求解
ax≡b(modp)
a
x
≡
b
(
mod
p
)
这样的问题
设
m=⌈p–√⌉
m
=
⌈
p
⌉
,将
x
x
分解为,那么
ax=ai∗m+j=ai∗m∗aj
a
x
=
a
i
∗
m
+
j
=
a
i
∗
m
∗
a
j
然后我们通过枚举
i
i
,来求解同余方程
变形得:
ai∗m∗aj+y∗p=b
a
i
∗
m
∗
a
j
+
y
∗
p
=
b
当前
aj
a
j
和
y
y
未知,将看为
x
x
,用扩展欧几里得求解即可
其实递推也可以
求解同余方程
当
i=0
i
=
0
时显然
aj=b
a
j
=
b
接下来每次左边乘上一个
am
a
m
,移项,得到
aj≡b∗inv(am)(modp)
a
j
≡
b
∗
i
n
v
(
a
m
)
(
mod
p
)
所以说
aj=b∗inv(am)
a
j
=
b
∗
i
n
v
(
a
m
)
递推下去即可
我们得到了
aj
a
j
,怎么得到
j
j
呢?
直接将的值映射到一个Hash表里面就好了
代码实现如下:
ll BSGS(ll a,ll b,ll p) {
if(a%p==0) return -1;
b%=p;
ll m=ceil(sqrt(p*1.0));
hash.clear();
ll in=1,d=1;
for(int i=0;i<m;i++) {
hash.insert(in,i);
in=(in*a)%p;
}
ll a_m_inv=get_inv(in,p);
for(int i=0;i<m;i++) {
ll cpt=hash.get(b);
if(cpt!=-1)
return i*m+cpt;
b=(b*a_m_inv)%p;
}
return -1;
}