BSGS 大步小步算法
BZOJ 3239
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<map>
const int maxn=1e6;
using namespace std;
typedef long long LL;
map<LL,int>s;
LL ny,mm,a,b,p,now=1;
LL ksm(LL a,int b,LL mod){
LL base=a,res=1;
while(b){
if(b&1) (res*=base)%=mod;
(base*=base)%=mod;
b>>=1;
}
return res;
}
int main()
{
while(scanf("%lld%lld%lld",&p,&a,&b)==3)
{
s.clear();
mm=sqrt(p); now=1;
a%=p; b%=p;
if(b==1) printf("0\n");
else if(a==b) printf("1\n");
else{
for(int i=1;i<=mm;i++){
now*=a;
now%=p;
if(!s[now]) s[now]=i;
}
if(s.count(b))
printf("%d\n",s[b]);
else{
int ans=-1;
ny=ksm(ksm(a,mm,p),p-2,p);
for(int i=2;i<=mm;i++)
{
b*=ny; b%=p;
if(s.count(b)) {ans=(i-1)*mm+s[b]; break; }
}
if(ans==-1) printf("no solution\n");
else printf("%d\n",ans);
}
}
}
return 0;
}