BSGS,baby step giant step,大步小步法,很形象的概括了这个算法的核心,算法用于解决一个很经典的问题:
,给定A,B,P,其中P为素数,求一个可行解x
大步小步法算法详解:猛戳这里
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;
#define ll long long
ll A,B,x,y,m,p,ans;
map<int,int> hash;
ll tmp,e,ny,sx;
ll pow(ll d,ll t){
ll ret=1;
for (;t;t>>=1,d=d*d%p)
if (t&1) ret=ret*d%p;
return ret;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("2417.in","r",stdin);
freopen("2417.out","w",stdout);
#endif
while (~scanf("%I64d%I64d%I64d",&p,&A,&B)){
hash.clear();
m=(int)sqrt(p+0.5);
tmp=A;e=1;
for (int i=0;i<=m;i++){
if (!hash[e]) hash[e]=i+1; //因为0也能算答案,但是不好判断,所以强制+1,在38行算答案的时候会把这个1减掉
e=e*tmp%p;
}
ny=pow(pow(A,m),p-2);
e=B;ans=-1;
for (int i=0;i<=m;i++){
if (hash[e]){
ans=(hash[e]-1)+i*m;
break;
}
e=e*ny%p;
}
if (ans==-1) puts("no solution");
else printf("%I64d\n",ans);
}
return 0;
}