Discrete Logging
Given a prime P, 2 <= P < 2 31, 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
HinThe 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) .
题解:这道题目是Baby-step giant-step的裸题吧,嗯嗯,不要忘了开long long就可以了。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 #include<cmath> 5 #include<cstring> 6 #include<map> 7 #define ll long long 8 using namespace std; 9 10 ll p,b,n; 11 12 int ex_gcd(ll a,ll b,ll &x,ll &y) 13 { 14 if (!b){x=1,y=0;return a;} 15 else 16 { 17 int fzy=ex_gcd(b,a%b,x,y); 18 int t=x;x=y; 19 y=t-a/b*y; 20 return fzy; 21 } 22 } 23 void solve() 24 { 25 ll m=(ll)sqrt(p); 26 map<int,int>num; 27 map<int,bool>app; 28 app[1]=1,num[1]=0; 29 ll zhi=1; 30 for (int i=1;i<=m-1;i++) 31 { 32 zhi=zhi*b%p; 33 if (!app[zhi]) 34 { 35 app[zhi]=1; 36 num[zhi]=i; 37 } 38 } 39 zhi=zhi*b%p; 40 ll x,y,nn=n; 41 int fzy=ex_gcd(zhi,p,x,y); 42 x=(x+p)%p; 43 for (int i=0;i<=m;i++) 44 { 45 if (app[nn]) 46 { 47 printf("%lld ",i*m+num[nn]); 48 return; 49 } 50 else nn=nn*x%p; 51 } 52 printf("no solution "); 53 } 54 int main() 55 { 56 while(~scanf("%d%d%d",&p,&b,&n)) 57 solve(); 58 }