poj2417(Baby-Step Giant-Step)

题目链接:http://poj.org/problem?id=2417

 

题意:求满足给出 P, N, B, 求满足条件 BL == N (mod P) 的最小 L, 若不存在则输出 no solution.

 

思路:Baby-Step Giant-Step 算法

设 L = kt − m,其中 t = ⌊sqrt(L)⌋, 0 <= m < t.那么 B^L = N (mod P) 就等价于 B^(kt − m) = N (mod P) 即 B^(kt) ∗ N^(−1) = B^m (mod P).我们可以先预处理出所有的 Bi (0 <= i < t) 记录在一个 hash 表里,然后枚举 k,计算 B^(kt) ∗ N^(−1) 的值,在hash表里找是否有符和条件的 m,若有则 kt − m 就是答案之一.所有答案中取最小的一个即可。

 

代码:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 #define ll long long
 5 using namespace std;
 6 
 7 const int MOD = 76543;
 8 int hs[MOD], head[MOD], next[MOD], id[MOD], top;
 9 
10 void insert(int x, int y){
11     int k = x % MOD;
12     hs[top] = x;
13     id[top] = y;
14     next[top] = head[k];
15     head[k] = top++;
16 }
17 
18 int find(int x){
19     int k = x % MOD;
20     for(int i = head[k]; i != -1; i = next[i]){
21         if(hs[i] == x) return id[i];
22     }
23     return -1;
24 }
25 
26 int BSGS(int a, int b, int n){
27     memset(head, -1, sizeof(head));
28     top = 1;
29     if(b == 1) return 0;
30     int m = sqrt(n * 1.0), j;
31     ll x = 1, p = 1;
32     for(int i = 0; i < m; ++i, p = p * a % n) insert(p * b % n, i);
33     for(ll i = m; ; i += m){
34         if( (j = find(x = x * p % n)) != -1 ) return i - j;
35         if(i > n) break;
36     }
37     return -1;
38 }
39 
40 int main(void){
41     int P, N, B;
42     while(~scanf("%d%d%d", &P, &B, &N)){
43         int ans = BSGS(B, N, P);
44         if(ans == -1) printf("no solution\n");
45         else printf("%d\n", ans);
46     }
47     return 0;
48 }
View Code

 

posted @ 2017-09-30 20:16  geloutingyu  阅读(274)  评论(0编辑  收藏  举报