题意:
对于A^X===B(mod C)中当A,B,C已知的情况下求X
算法流程如下:
i)for i=0 i to100 if(A^i===B(mod c)) 那么i就是答案 否则执行下一步
ii)令d=0,D=1 执行下叙循环
while((tmp=gcd(A,C))!=1){
if(B%tmp)return -1;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
iii)令m=ceil(sqrt(C))
iv)i从0到m循环将(i,A^i%C)插入Hash表中
v)求得K=quick_mod(A,m,C),令i=0;如果i>m,执行下一步,否则求 DX=B(mod C)在[0,C-1]的解,并在Hash表中查询,如果查到返回i*m+x否则D=DK%C i++继续循环
vi)返回-1
ACcode:
#include <iostream>
#include <cstdio>
#include <math.h>
#define maxn 65535
#define ll long long
using namespace std;
struct Hash{
int a,b,next;
}my[maxn<<1];
int flag[maxn<<1];
int top,idx;
void ins(int a,int b){
int k=b&maxn;
if(flag[k]!=idx){
flag[k]=idx;
my[k].next=-1;
my[k].a=a;
my[k].b=b;
}
while(my[k].next!=-1){
if(my[k].b==b)return;
k=my[k].next;
}
my[k].next=++top;
my[top].next=-1;
my[top].a=a;
my[top].b=b;
}
int find(int b){
int k=b&maxn;
if(flag[k]!=idx)return -1;
while(k!=-1){
if(my[k].b==b)
return my[k].a;
k=my[k].next;
}
return -1;
}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int exgcd(int a,int b,int &x,int &y){
if(a==0&&b==0)return -1;
if(b==0){x=1,y=0;return a;}
int d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int inval(int a,int b,int n){
int x,y,e;
exgcd(a,n,x,y);
e=(long long)x*b%n;
return e<0?e+n:e;
}
int powmod(long long a,int b,int c){
long long ret=1%c;
a%=c;
while(b){
if(b&1)
ret=ret*a%c;
a=a*a%c;
b>>=1;
}
return ret;
}
int bsgs(int A,int B,int C){
top=maxn;
++idx;
long long buf=1%C,D=buf,K;
int i,d=0,tmp;
for(i=0;i<=100;buf=buf*A%C,++i)
if(buf==B)
return i;
while((tmp=gcd(A,C))!=1){
if(B%tmp)return -1;
++d;
C/=tmp;
B/=tmp;
D=D*A/tmp%C;
}
int M=(int)ceil(sqrt((double)C));
for(buf=1%C,i=0;i<=M;buf=buf*A%C,++i)
ins(i,buf);
for(i=0,K=powmod((long long)A,M,C);i<=M;D=D*K%C,++i){
tmp=inval((int)D,B,C);
int w;
if(tmp>=0 && (w=find(tmp))!=-1)
return i*M+w+d;
}
return -1;
}
int main(){
int a,b,c;
while(scanf("%d%d%d",&c,&a,&b)!=EOF){
b%=c;
int tmp=bsgs(a,b,c);
if(tmp<0)puts("no solution");
else printf("%d\n",tmp);
}
return 0;
}