poj2417 Baby-StepGiant-StepAlgorithm a^x=b%P

时间:2021-10-26 00:26:04
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
struct Node{
int idx;
LL val;
Node(int cidx=, LL cval=){
idx=cidx;
val=cval;
}
bool operator <(const Node &rhs)const{
return val<rhs.val||( val == rhs.val && idx<rhs.idx );
}
}P[];
LL pow_mod(LL a, LL n, LL mod)
{
LL ans=;
while(n)
{
if(n&)ans=(ans*a)%mod;
n>>=;
a=(a*a)%mod;
}
return ans;
}
int bitsearch(LL d,int n)
{
int L=,R=n-;
while(L<=R)
{
int mid=(L+R)>>;
if(P[mid].val==d) return P[mid].idx;
if(P[mid].val<d) L=mid+;
else R=mid-;
}
return -;
}
LL log_mod(LL a, LL b, LL n)
{
LL m,v,e=;
m=(sqrt(n+0.5))+;
v=pow_mod(a,n-m-,n);
P[]=Node(,);
for(int i=; i<m; i++)
{
e=(e*a)%n;
P[i]=Node(i,e);
}
sort(P,P+m);
int cnt=;
for(int i=; i<m; i++)
if(P[i].val!=P[cnt-].val) P[cnt++]=P[i];
for(int i=; i<m; i++)
{
int loc=bitsearch(b,cnt);
if(loc!=-){
return i*m+loc;
}
b=(b*v)%n;
} return -;
}
int main()
{
LL P,B,N;
while(scanf("%I64d%I64d%I64d",&P,&B,&N)==)
{
LL d =log_mod(B,N,P);
if(d==-)puts("no solution");
else printf("%I64d\n",d);
}
return ;
}