D e s c r i p t i o n Description Description
给定 a , b , p a,b,p a,b,p,求一个 x x x使其满足 a x ≡ b ( m o d p ) a^x\equiv b\ \left(mod\ p\right) ax≡b (mod p)
B S G S BSGS BSGS
B
S
G
S
BSGS
BSGS可以解决
p
p
p为质数的情况
令
m
=
⌈
p
⌉
m=\lceil \sqrt p\rceil
m=⌈p⌉
令 x = i ⋅ m − k x=i\cdot m-k x=i⋅m−k
有 a i ⋅ m − k ≡ b ( m o d p ) a^{i\cdot m-k} \equiv b\ (mod\ p) ai⋅m−k≡b (mod p)
两边同乘 a k a^k ak 得 a i ⋅ m ≡ b ⋅ a k ( m o d p ) a^{i\cdot m}\equiv b\cdot a^k\ (mod\ p) ai⋅m≡b⋅ak (mod p)
我们先将右边的 b ⋅ a k b\cdot a^k b⋅ak 全部求出来存到一个表里,这样预处理时间复杂度为 p \sqrt p p
之后再枚举 i i i 到 p \sqrt p p ,看表里有没有 a i ⋅ m m o d p a^{i\cdot m}\ mod\ p ai⋅m mod p,有的话就有一组解
再反向求出 x x x即可
E X B S G S EXBSGS EXBSGS
当
p
p
p不是质数时
令
g
=
g
c
d
(
a
,
p
)
g=gcd(a,p)
g=gcd(a,p)
有
a
x
−
1
⋅
a
g
⋅
g
≡
b
g
⋅
g
(
m
o
d
p
g
⋅
g
)
a^{x-1}\cdot \dfrac{a}{g}\cdot g \equiv \dfrac{b}{g}\cdot g\ \left(mod\ \dfrac{p}{g}\cdot g\right)
ax−1⋅ga⋅g≡gb⋅g (mod gp⋅g)
把那个
g
g
g除掉
a
x
−
1
⋅
a
g
≡
b
g
(
m
o
d
p
g
)
a^{x-1}\cdot \dfrac{a}{g} \equiv \dfrac{b}{g}\ \left(mod\ \dfrac{p}{g} \right)
ax−1⋅ga≡gb (mod gp)
然后重复这个过程直到
a
,
p
a,p
a,p互质
p p p除掉 g c d ( a , p ) gcd(a,p) gcd(a,p)后可能仍与 a a a有公约数,与 a g c d ( a , p ) \frac{a}{gcd(a,p)} gcd(a,p)a互质
显然,在这个过程中如果 p p p不能被 b b b整除就无解
到最后会得到这样的方程
a
x
−
i
⋅
c
≡
t
(
m
o
d
p
)
a^{x-i}\cdot c\equiv t\ \left(mod\ p\right)
ax−i⋅c≡t (mod p)
c
c
c是由
a
a
a的幂除以若干个因子得到的
c
,
t
c,t
c,t肯定互质
两边乘以
c
−
1
c^{-1}
c−1(逆元)
a
x
−
i
≡
t
⋅
c
−
1
(
m
o
d
p
)
a^{x-i}\equiv t\cdot c^{-1}\ \left(mod\ p\right)
ax−i≡t⋅c−1 (mod p)
用
B
S
G
S
BSGS
BSGS对
x
−
i
x-i
x−i求解即可
最后记得加上
i
i
i
C o d e Code Code
B S G S BSGS BSGS
ksm(a,b);//return a^b
gcd(a,b);//return gcd(a,b)
//{{{bsgs
int bsgs (int a,int b,int p)//return a^x ≡ b mod p 's x
{
a%=p;
if (!a&&!b) return 1;
if (!a) return -1;
int m=sqrt(p);
map <int,int> mp;//这里用的map 也可以自己打个哈希
int t=b%p;
mp[t]=0;
for (int i=1;i<=m;++i) mp[t=1ll*t*a%p]=i;
t=1;
int mi=ksm(a,m);
for (int i=1;1ll*i*i<=p+1;++i){
t=1ll*t*mi%p;
if (mp.count(t)) return ((1ll*i*m%p-mp[t])%p+p)%p;
}
return -1;
}
//}}}
E X B S G S EXBSGS EXBSGS
//{{{exbsgs
int exbsgs (int a,int b,int p)//a^x ≡ b mod p 's x
{
if (b==1) return 0;
int cnt=0,t=1;
for (int g=gcd(a,p);g!=1;g=gcd(a,p)){
if (b%g) return -1;
++cnt,b/=g,p/=g;
t=1ll*t*a/g%p;
if (b==t) return cnt;
}
int x=bsgs(a,1ll*ksm(t,p-2)*b%p,p);
if (x!=-1) x+=cnt;
return x;
}
//}}}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧