最害怕不会的东西终于学了
BSGS算法 Baby_Step_Giant_step算法(北上广深新一线算法或者拔山盖世算法)
是解决离散对数问题的利器
思路:不妨设
且
在这一顿骚操作后
原式变为:
由于j小于m所以预处理右边是
右边枚举i不大于m
综上这是一个根号算法解决了
离散对数问题最小解的方法
#include<bits/stdc++.h>
using namespace std;
typedef int INT;
#define int long long
int b,p,n;
map<int,int> mmp;
inline int quick_pow(int x,int k){
int ret=1;
while(k){
if(k%2==1){
ret=ret*x%p;
}
x=x*x%p;
k/=2;
}
return ret;
}
INT main(){
// freopen("test.in","r",stdin);
cin>>p>>b>>n;
if(b%p==0){
cout<<"no solution";
return 0;
}
int m=ceil(sqrt(p));
mmp[n%p]=0;
for(int i=1;i<=m;i++){
mmp[quick_pow(b,i)*n%p]=i;
}
int t=quick_pow(b,m),ans=1;
for(int i=1;i<=m;i++){
ans=ans*t%p;
if(mmp[ans]){
int key=i*m-mmp[ans];
cout<<((key%p)+p)%p;
return 0;
}
}
cout<<"no solution";
return 0;
}