BSGS学习笔记
Problem
Solution
\[a^x\equiv b \mod p\\
a^{i*m-j}\equiv b \mod p\\
(a^m)^i\equiv b\times a^j \mod p
\]
meet in middle
取\(m=\sqrt p\)
将每个\(b\times a^j\)建表记录下来
然后\((a^m)^i\)一路算过去
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
int p;
map<int,bool>hs;
map<int,int>hs2;
int Pow(int x,int y){
int re=1;
while(y){
if(y&1)re=(re*x)%p;
y>>=1;
x=(x*x)%p;
}
return re%p;
}
void format(int a,int b){
hs.clear();hs2.clear();
int hh=sqrt(p);b%=p;
for(int j=0;j<=hh;++j){
int pp=b*Pow(a,j)%p;
hs[pp]=true,hs2[pp]=j;
}
}
int fk(int a,int b){
if(a==0)return b==0?1:-1;
int hh=sqrt(p);
int m=Pow(a,hh),d,j;
for(int i=0;i<=hh;++i){
d=Pow(m,i);
if(hs[d]){
j=hs2[d];
if(j>=0&&i*hh-j>=0)
return i*hh-j;
}
}
return -1;
}
signed main(){
int b,n;
while(~scanf("%lld%lld%lld",&p,&b,&n)){
format(b,n);
int ans=fk(b,n);
if(ans==-1)puts("no solution");
else printf("%lld\n",ans);
}
return 0;
}
/*
5 2 1
5 2 2
5 2 3
5 2 4
5 3 1
5 3 2
5 3 3
5 3 4
5 4 1
5 4 2
5 4 3
5 4 4
12345701 2 1111111
1111111121 65537 1111111111
*/