Description
Given a prime P, 2 <= P < 231, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that
BL== N (mod P)
Input
Read several lines of input, each containing P,B,N separated by a space.
Output
For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print "no solution".
Sample Input
5 2 1 5 2 2 5 2 3 5 2 4 5 3 1 5 3 2 5 3 3 5 3 4 5 4 1 5 4 2 5 4 3 5 4 4 12345701 2 1111111 1111111121 65537 1111111111
Sample Output
0 1 3 2 0 3 1 2 0 no solution no solution 1 9584351 462803587
Hint
The solution to this problem requires a well known result in number theory that is probably expected of you for Putnam but not ACM competitions. It is Fermat's theorem that states
B(P-1)== 1 (mod P)
for any prime P and some other (fairly rare) numbers known as base-B pseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichael numbers, are pseudoprimes for every base between 2 and P-1. A corollary to Fermat's theorem is that for any m
B(-m)== B(P-1-m)(mod P)
BSGS算法模板
从Navi拿了一张截图
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 int MOD=250000; 9 lol hash[300001],id[300001]; 10 void insert(lol x,lol d) 11 { 12 lol pos=x%MOD; 13 while (1) 14 { 15 if (hash[pos]==-1||hash[pos]==x) 16 { 17 hash[pos]=x; 18 id[pos]=d; 19 return; 20 } 21 pos++; 22 if (pos>=MOD) pos-=MOD; 23 } 24 } 25 bool count(lol x) 26 { 27 lol pos=x%MOD; 28 while (1) 29 { 30 if (hash[pos]==-1) return 0; 31 if (hash[pos]==x) return 1; 32 pos++; 33 if (pos>=MOD) pos-=MOD; 34 } 35 } 36 lol query(lol x) 37 { 38 lol pos=x%MOD; 39 while (1) 40 { 41 if (hash[pos]==x) return id[pos]; 42 pos++; 43 if (pos>=MOD) pos-=MOD; 44 } 45 } 46 lol qpow(lol x,lol y,lol Mod) 47 { 48 lol res=1; 49 while (y) 50 { 51 if (y&1) res=res*x%Mod; 52 x=x*x%Mod; 53 y>>=1; 54 } 55 return res; 56 } 57 lol BSGS(lol a,lol b,lol Mod) 58 {int i; 59 memset(hash,-1,sizeof(hash)); 60 memset(id,0,sizeof(id)); 61 lol tim=ceil(sqrt((double)Mod)); 62 lol tmp=b%Mod; 63 for (i=0;i<=tim;i++) 64 { 65 insert(tmp,i); 66 tmp=tmp*a%Mod; 67 } 68 lol t=tmp=qpow(a,tim,Mod); 69 for (i=1;i<=tim;i++) 70 { 71 if (count(tmp)) 72 return i*tim-query(tmp); 73 tmp=tmp*t%Mod; 74 } 75 return -1; 76 } 77 int main() 78 {lol p,a,b,ans; 79 while (~scanf("%lld%lld%lld",&p,&a,&b)) 80 { 81 if ((ans=BSGS(a,b,p))==-1) printf("no solution "); 82 else printf("%lld ",ans); 83 } 84 }