Baby Step Gaint Step算法
这个算法是解决什么的呢?
求关于
y
y
y的方程
x
y
≡
z
(
m
o
d
p
)
x^y\equiv z\ (\bmod\ p)
xy≡z (mod p)
的最小整数解
其中保证
(
x
,
p
)
=
1
(x,p)=1
(x,p)=1
其实还是挺暴力的…
为了便于解决,我们把
y
y
y表示成
i
m
−
j
im-j
im−j的形式
那么原来的式子就变成了
x
i
m
−
j
≡
z
(
m
o
d
p
)
x^{im-j}\equiv z\ (\bmod\ p)
xim−j≡z (mod p)
x
i
m
≡
z
⋅
x
j
(
m
o
d
p
)
x^{im}\equiv z\cdot x^j\ (\bmod \ p)
xim≡z⋅xj (mod p)
那么我们枚举每一个
j
∈
[
0
,
m
]
j\in[0,m]
j∈[0,m],记录出
z
⋅
x
j
z\cdot x^j
z⋅xj的值
然后枚举每一个
i
i
i,看
x
i
m
x^{im}
xim的值之前有没有出现过,如果出现过就输出
如果一直没有出现过就无解
m
m
m显然取
p
\sqrt{p}
p的时候复杂度最优,所以BSGS算法的复杂度是
O
(
p
)
O(\sqrt p)
O(p)
但是注意记录的时候最好使用哈希,用STL的话不要用
m
a
p
map
map,因为
m
a
p
map
map会多一个
l
o
g
log
log
用STL就用unordered_map
但是这个东西c++11才有,如果编译器不能运行的话,在编译的时候加一行指令
-std=c++11
就可以啦
给出关键代码:
unordered_map<ll,ll> var;
ll BSGS(ll x,ll z){
var.clear();
ll m=ceil(sqrt(mod));
for(ll i=0,j=z;i<=m;i++,j=j*x%mod)var[j]=i;
for(ll i=1,j=Qpow(x,m),k=j;i<=m;i++,j=j*k%mod)if(var.count(j))return i*m-var[j];
return -2;
}
模板题:
[SDOI2011]计算器