BSGS (Baby Step-Giant Step 大步小步算法)
拔山盖世算法
用于求解高次同余方程
a
x
≡
b
(
m
o
d
  
p
)
a^x\equiv b(\mod p)
ax≡b(modp),其中
a
,
p
a,p
a,p互质
我们令
t
=
⌊
p
⌋
t=\lfloor{\sqrt{p}}\rfloor
t=⌊p⌋
并将
x
x
x表示为
x
=
i
∗
t
−
j
x=i*t-j
x=i∗t−j,其中
0
<
=
j
<
=
t
0<=j<=t
0<=j<=t
则方程变为
a
i
∗
t
−
j
≡
b
(
m
o
d
  
p
)
⇒
(
a
t
)
i
≡
b
∗
a
j
(
m
o
d
  
p
)
a^{i*t-j}\equiv b(\mod p)\Rightarrow (a^t)^i\equiv b*a^j(\mod p)
ai∗t−j≡b(modp)⇒(at)i≡b∗aj(modp)
对于所有
j
∈
[
0
,
t
]
,
j
∈
K
j\in[0,t],j\in K
j∈[0,t],j∈K
把
b
∗
a
j
m
o
d
  
p
b*a^j\mod p
b∗ajmodp插入hash表
枚举所有
i
∈
[
0
,
t
]
,
i
∈
K
i\in [0,t],i \in K
i∈[0,t],i∈K
查询
(
a
t
)
i
m
o
d
  
p
(a^t)^i\mod p
(at)imodp的值是否存在于hash表中
若存在即代表找到一个解
x
=
i
∗
t
−
j
x=i*t-j
x=i∗t−j
若枚举完所有可能的
i
i
i在hash表中都不存在对应的
j
j
j
则可判定原方程无解
特别的,若有
a
m
o
d
  
p
=
=
0
a\mod p==0
amodp==0且
b
m
o
d
  
p
!
=
0
b \mod p\ !=0
bmodp !=0
则代表原方程无解
BSGS果题链接&&算法主要代码
Discrete Logging POJ - 2417
map<int,int> hash;
map<int,bool> vis;
lt BSGS(lt a,lt b,lt p)
{
hash.clear(); vis.clear();
lt t=sqrt(p)+1; b%=p;
for(int j=0;j<t;++j)//插入所有b*(a^j) mod p
{
lt tt=b*qpow(a,j,p)%p;
hash[tt]=j; vis[tt]=true;
}
a=qpow(a,t,p);
if(a==0)return b==0?1:-1;//特判 方程无解 或 最小非负整数解为1
for(int i=0;i<=t;++i)
{
lt tt=qpow(a,i,p);//在hash表中查找(a^t)^i mod p对应的j
if(vis[tt]){
int j=hash[tt];
if(j>=0&&i*t-j>=0) return i*t-j;
}
}
return -1;
}