BSGS与exBSGS
大步小步(BSGS)
模板题
给定 \(a,b,p\) 求最小 \(x\) 满足 \(a^x \equiv b \pmod{p}\) 其中 \(a,p\) 互质
求法
假定 \(m=\left \lceil \sqrt p \right \rceil\),\(x=i\cdot m-j\) 其中 \(i,j\leq m\)
原式可化为 \(a^{i\cdot m-j} \equiv b \pmod{p}\)
即 \(a^{i\cdot m} \equiv b\cdot a^j \pmod{p}\)
由于 \(a,p\) 互质,显然 \(a^{1\sim p-1}\bmod p\) 互不相同
我们枚举 \(j\),将 \(b\cdot a^j\bmod p\) 存入 \(\textstyle{hash}\) 表
然后枚举 \(i\),从 \(\textstyle{hash}\) 表里找出第一个 \(j\) 满足 \(a^{i\cdot m} \equiv b\cdot a^j \pmod{p}\)
此时 \(x=i\cdot m-j\) 即为所求
P3846 [TJOI2007] 可爱的质数/【模板】BSGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b,p;
map <int,int> mp;
inline int qpow(int x,int idx){
if(!idx) return 1;
int t=qpow(x,idx>>1);
if(idx&1) return t*t%p*x%p;
return t*t%p;
}
inline int BSGS(){
b%=p;
int t=sqrt(p)+1;
for(int i=0;i<t;++i)
mp[b*qpow(a,i)%p]=i;
a=qpow(a,t);
if(!a) return !b?1:-1;
for(int i=1;i<=t;++i){
int v=qpow(a,i);
if(mp.find(v)==mp.end()) continue;
int j=mp[v];
if(i*t-j>=0) return i*t-j;
}
return -1;
}
signed main(){
scanf("%lld%lld%lld",&p,&a,&b);
int ans=BSGS();
if(ans==-1) puts("no solution");
else printf("%lld\n",ans);
}
exBSGS
P4195 【模板】扩展 BSGS/exBSGS
回忆$BSGS$算法,给定整数$a,b,p$,其中$a,p$互质,求方程$a^x\equiv b\ (mod\ p)$的最小整数解$x$
做法:设$x=i\times m-j,m=\left \lceil \sqrt p \right \rceil,1\le j\le m,1\le i\le m$
方程变为$a^{im-j}\equiv b\ (mod\ p)$
化一下$(a^m)^i\equiv b\times a^j\ (mod\ p)$
这时只要把$(a^m)^i$和$b\times a^j$预处理出来丢到哈希表里就做完了
而现在的$a,p$不互质了,所以我们要考虑其他的方法,也就是$\text{Ex\_BSGS}$
那么我们设$g=gcd(a,p)$
根据模的分配率,方程变为$\frac{a^x}{g}\equiv \frac{b}{g}\ (mod\ \frac{p}{g})$
无解情况就是$g\nmid b$并且$b\ne 1$
我们来证明一下
设$a'=\frac{a}{g},p'=\frac{p}{g}$,那么$a=a'g,p=p'g$
代入到原方程中变为$(a'g)^x\equiv b\ (mod\ p'g)$
$$a'^xg^x+yp'g=b$$
$$g(a'^xg^{x-1}+yp')=b$$
这样子$g$就是$b$的因子,而只有在$b=1$时,$a^0=1$,其余情况若$g\nmid b$,方程无解
证毕
那么我们再把上面的式子化一下变为$a^{x-1}\times\frac{a}{g}\equiv \frac{b}{g}\ (mod\ \frac{p}{g})$
而$\frac{p}{g}$一定是比$p$小的,所以可以一直约到$a,\frac{p}{g}$互质
设$na=\prod_{i=1}^k\frac{a}{g_i}$
原式就可以写成$a^{x-k}\equiv \frac{b}{\prod_{i=1}^k g\times na}(mod\ \frac{p}{\prod_{i=1}^kg})$ ,$k$是做了几次化简
这样子就可以用$BSGS$求解啦
有一点需要注意,因为是在模意义下运算,所以除以$na$时要乘其逆元
因为最后一直化到了$\frac{a}{\prod_{i=1}^kg}$和$\frac{p}{\prod_{i=1}^kg}$互质,所以$na$和$\frac{p}{\prod_{i=1}^kg}$看起来也很互质
就可以用扩欧求逆元了