POJ 2417 Discrete Logging(离散对数-小步大步算法)

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 
    B
L
 == 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".
 
题目大意:求离散对数,B^L = N (mod P),其中P是素数,求L。
思路:大步小步算法的模板题。
PS:白书上的模板少了个ceil向上取整……
PS:用map来哈希TLE了。速度和手写哈希原来差距这么大……
 
代码(47MS):
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int SIZEH = 65537;
10 
11 struct hash_map {
12     int head[SIZEH], size;
13     int next[SIZEH];
14     LL state[SIZEH], val[SIZEH];
15 
16     void init() {
17         memset(head, -1, sizeof(head));
18         size = 0;
19     }
20 
21     void insert(LL st, LL sv) {
22         LL h = st % SIZEH;
23         for(int p = head[h]; ~p; p = next[p])
24             if(state[p] == st) return ;
25         state[size] = st; val[size] = sv;
26         next[size] = head[h]; head[h] = size++;
27     }
28 
29     LL find(LL st) {
30         LL h = st % SIZEH;
31         for(int p = head[h]; ~p; p = next[p])
32             if(state[p] == st) return val[p];
33         return -1;
34     }
35 } hashmap;
36 
37 LL inv(LL a, LL n) {
38     if(a == 1) return 1;
39     return ((n - n / a) * inv(n % a, n)) % n;
40 }
41 
42 LL pow_mod(LL x, LL p, LL n) {
43     LL ret = 1;
44     while(p) {
45         if(p & 1) ret = (ret * x) % n;
46         x = (x * x) % n;
47         p >>= 1;
48     }
49     return ret;
50 }
51 
52 LL BabyStep(LL a, LL b, LL n) {
53     LL e = 1, m = LL(ceil(sqrt(n + 0.5)));
54     hashmap.init();
55     hashmap.insert(1, 0);
56     for(int i = 1; i < m; ++i) {
57         e = (e * a) % n;
58         hashmap.insert(e, i);
59     }
60     LL v = inv(pow_mod(a, m, n), n);
61     for(int i = 0; i < m; ++i) {
62         LL t = hashmap.find(b);
63         if(t != -1) return i * m + t;
64         b = (b * v) % n;
65     }
66     return -1;
67 }
68 
69 int main() {
70     LL p, b, n;
71     while(cin>>p>>b>>n) {
72         LL ans = BabyStep(b, n, p);
73         if(ans == -1) puts("no solution");
74         else cout<<ans<<endl;
75     }
76 }
View Code
原文地址:https://www.cnblogs.com/oyking/p/3631505.html