Discrete Logging
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 5120 | Accepted: 2319 |
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
思路:baby_step,giant_step算法模板题
1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdlib.h> 5 #include<queue> 6 #include<vector> 7 #include<math.h> 8 #include<string.h> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long LL; 13 LL mod[65539]; 14 bool judge(LL n) 15 { 16 LL ac=sqrt(1.0*n); 17 if(ac*ac==n) 18 return true; 19 else return false; 20 } 21 map<LL,LL>my; 22 set<LL>que; 23 set<LL>::iterator it; 24 LL quick(LL n,LL m,LL p); 25 LL gcd(LL n,LL m) 26 { 27 if(m==0) 28 return n; 29 else return gcd(m,n%m); 30 } 31 pair<LL,LL>Pc(LL n,LL m) 32 { 33 if(m==0) 34 return make_pair(1,0); 35 else 36 { 37 pair<LL,LL>N=Pc(m,n%m); 38 return make_pair(N.second,N.first-(n/m)*N.second); 39 } 40 } 41 typedef struct pp 42 { 43 LL x; 44 LL id; 45 } ss; 46 ss table[655390]; 47 ss tt[655390]; 48 bool cmp(pp p,pp q) 49 { 50 if(p.x==q.x) 51 return p.id<q.id; 52 return p.x<q.x; 53 } 54 int main(void) 55 { 56 LL P,B,N; 57 while(scanf("%lld %lld %lld",&P,&B,&N)!=EOF) 58 { 59 bool a=judge(P); 60 LL ask=sqrt(1.0*P); 61 if(!a) 62 ask+=1; 63 int i,j; 64 mod[0]=1; 65 int vv=0; 66 table[0].id=0; 67 table[0].x=1; 68 int cn=1; 69 for(i=1; i<=ask; i++) 70 { 71 mod[i]=mod[i-1]*B%P; 72 table[i].id=i; 73 table[i].x=mod[i]; 74 } 75 sort(table,table+ask+1,cmp); 76 tt[0].id=table[0].id; 77 tt[0].x=table[0].x; 78 LL yy=tt[0].x; 79 for(i=1;i<=ask;i++) 80 { 81 if(table[i].x!=yy) 82 { 83 yy=table[i].x; 84 tt[cn].x=yy; 85 tt[cn].id=table[i].id; 86 cn++; 87 } 88 } 89 int fl=0; 90 LL ack; 91 LL nn=quick(B,P-2,P); 92 nn=quick(nn,ask,P); 93 LL ni=1; 94 for(i=0; i<=ask; i++) 95 { 96 LL ap=ni*N%P; 97 ni%=P; 98 int l=0; 99 int r=cn-1; 100 LL ic=-1; 101 while(l<=r) 102 { 103 int mid=(l+r)/2; 104 if(tt[mid].x>=ap) 105 { 106 ic=mid; 107 r=mid-1; 108 ack=tt[ic].id; 109 } 110 else l=mid+1; 111 } 112 if(ic!=-1&&tt[ic].x==ap) 113 { 114 //printf("%lld ",table[ic].x);printf("%d ",i) ; 115 fl=1; 116 break; 117 } 118 ni=(ni*nn)%P; 119 } 120 if(!fl) 121 printf("no solution "); 122 else printf("%lld ",ack+(LL)i*ask); 123 } 124 return 0; 125 } 126 LL quick(LL n,LL m,LL p) 127 { 128 n%=p; 129 LL ans=1; 130 while(m) 131 { 132 if(m&1) 133 { 134 ans=ans*n%p; 135 } 136 n=n*n%p; 137 m/=2; 138 } 139 return ans; 140 }