码迷,mamicode.com
首页 > 其他好文 > 详细

Discrete Logging

时间:2017-05-19 16:51:02      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:class   lin   table   exp   ini   1.2   log   int   tween   

Discrete Logging
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 5865   Accepted: 2618

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".

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) .

Source

BSGS模板题
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<map>
 6 #define LL long long 
 7 using namespace std;
 8 LL a,b,c;
 9 map<LL,LL>mp;
10 LL fastpow(LL a,LL p,LL c)
11 {
12     LL base=a;LL ans=1;
13     while(p!=0)
14     {
15         if(p%2==1)ans=(ans*base)%c;
16         base=(base*base)%c;
17         p=p/2;
18     }
19     return ans;
20 }
21 int main()
22 {
23     // a^x = b (mod c)
24     while(scanf("%lld%lld%lld",&c,&a,&b)!=EOF)
25     {
26         LL m=ceil(sqrt(c));// 注意要向上取整 
27         mp.clear();
28         if(a%c==0)
29         {
30         printf("no solution\n");
31         continue;
32         }
33         // 费马小定理的有解条件 
34         LL ans;//储存每一次枚举的结果 b* a^j
35         for(LL j=0;j<=m;j++)  // a^(i*m) = b * a^j
36         {
37             if(j==0)
38             {
39                 ans=b%c;
40                 mp[ans]=j;// 处理 a^0 = 1 
41                 continue;
42             }
43             ans=(ans*a)%c;// a^j 
44             mp[ans]=j;// 储存每一次枚举的结果 
45         }
46         LL t=fastpow(a,m,c);
47         ans=1;//a ^(i*m)
48         LL flag=0;
49         for(LL i=1;i<=m;i++)
50         {
51             ans=(ans*t)%c;
52             if(mp[ans])
53             {
54                 LL out=i*m-mp[ans];// x= i*m-j
55                 printf("%lld\n",(out%c+c)%c);
56                 flag=1;
57                 break;
58             }
59             
60         }
61         if(!flag)
62         printf("no solution\n");    
63     }
64     
65     return 0;
66 }

 

Discrete Logging

标签:class   lin   table   exp   ini   1.2   log   int   tween   

原文地址:http://www.cnblogs.com/zwfymqz/p/6878968.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!