1 Accepted 8508K 579MS C++ 2237B/**
2 hash的强大,,还是高次方程,不过要求n不一定是素数
3 **/
4 #include <iostream>
5 #include <cstdio>
6 #include <cmath>
7 #include <cstring>
8 #include <algorithm>
9 using namespace std;
10 long long a,b,n;
11 const int maxn = 499991;
12 bool Hash[maxn];
13 long long val[maxn];
14 long long idx[maxn];
15
16 long long gcd(long long a,long long b){
17 if(b==0)
18 return a;
19 return gcd(b,a%b);
20 }
21
22 void ex_gcd(long long a,long long b,long long &x,long long &y){
23 if(b==0){
24 x=1;
25 y=0;
26 return ;
27 }
28 ex_gcd(b,a%b,x,y);
29 long long tmp= x-(a/b)*y;
30 x = y;
31 y = tmp;
32 return ;
33 }
34
35 void Insert(long long id,long long num){
36 long long k = num%maxn;
37 while(Hash[k]&&val[k]!=num){
38 k++;
39 if(k==maxn) k = k-maxn;
40 }
41 if(!Hash[k]){
42 Hash[k] = true;
43 val[k] = num;
44 idx[k] = id;
45 }
46 return;
47 }
48
49 long long found(long long num){
50 long long k = num%maxn;
51 while(Hash[k]&&val[k]!=num){
52 k++;
53 if(k==maxn) k-=maxn;
54 }
55 if(Hash[k]){
56 return idx[k];
57 }
58 return -1;
59 }
60
61 long long baby_step(long long a,long long b,long long n){
62 long long temp =1;
63 long long i;
64 for(i=0;i<=100;i++){
65 if(temp==b%n) return i;
66 temp = temp*a%n;
67 }
68 long long tmp,d =1,cnt=0;
69 memset(Hash,false,sizeof(Hash));
70 memset(val,-1,sizeof(val));
71 memset(idx,-1,sizeof(idx));
72
73 while((tmp=gcd(a,n))!=1){
74 if(b%tmp)
75 return -1;
76 cnt++;
77 n = n/tmp;
78 b = b/tmp;
79 d =d*a/tmp%n;
80 }
81 long long cur =1;
82 long long m = ceil(sqrt(n+0.5));
83 for(i=0;i<m;i++){
84 Insert(i,cur);
85 cur = cur*a%n;
86 }
87 long long x,y;
88 for(i=0;i<m;i++){
89 ex_gcd(d,n,x,y);
90 x = x*b%n;
91 x = (x%n+n)%n;
92 long long k = found(x);
93 if(k!=-1)
94 return i*m+k+cnt;
95 d = d*cur%n;
96 }
97 return -1;
98 }
99
100 int main()
101 {
102 while(scanf("%I64d%I64d%I64d",&a,&n,&b)==3){
103 if(a==0&&b==0&&n==0)
104 break;
105 long long res = baby_step(a,b,n);
106 if(res==-1){
107 printf("No Solution\n");
108 }else{
109 printf("%I64d\n",res);
110 }
111 }
112 return 0;
113 }