BSGS&ExBSGS
求解形如
\[a^x\equiv b\pmod p\]
的高次同余方程
BSGS
假装\(gcd(a,p)=1\)。
设\(m=\lceil\sqrt p \rceil\)
然后把\(x\)分解成
\[x=i*m+j\]
的形式。
\[a^x\equiv b\pmod p\]
\[a^{i*m+j}\equiv b\pmod p\]
\[a^{im}\equiv b/a^j\pmod p\]
这时我们发现,\(1≤j≤m-1\),也就是说枚举\(j\)是非常简单的。
这样我们就可以把\(m-1\)个\(j\)全都存起来,存到哈希表中,然后枚举\(i\),这样就可以在\(O(\sqrt n + log (n))\)的时间内求出解了。(分块 + map)
(时间复杂度是wyh在网上找的,自己不会证qwq
ExBSGS
刚刚我们假装\(gcd(a,p)=1\),那要是没有这个条件怎么办呢?
很简单,我们只要通过把两边同时除以 他们的 gcd 就好啦qwq
设\(g=gcd(a,p)\),如果\(g\not| b\),显然如果\(p=1\)则\(x=0\),否则方程无解
我们就得到
\[a^{x-1}*\frac{a}{g}\equiv \frac{b}{g}\pmod {\frac{p}{g}}\]
\[a^{x-1}\equiv \frac{b}{a}\pmod \frac{p}{g}\]
这样一直做下去,直到\(g=1\)为止。
有一个误区(对于我这种蒟蒻)就是\(a\)和\(b/g\)不一定互质。这是zzy学长告诉wyh的qwq,还是学长好啊qwq。
好感动啊。。。
Code
typedef long long ll;
map<ll,ll> ma;
inline ll bsgs(ll a,ll b)//解a^x同余b (%mod)
{
a%=mod;b%=mod;
ma.clear();
ll m=ll(sqrt(mod+1)),e=1;
for(int j=0;j<m;++j)
{
if(!ma.count(e)) ma[e]=j;
e=e*a%mod;
}
if(gcd(e,mod)!=1) return -1;
ll inv=inverse(e);//逆元
for(int i=0;i<m;++i)
{
if(ma.count(b)) return i*m+ma[b];
b=b*inv%mod;
}
return -1;
}