Discrete Logging

2018-06-17 22:34:42来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

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

Waterloo Local 2002.01.26
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 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:newlib 中的 crt0 流程分析

下一篇:c++利用MFC实现绘制两个矩形,并标识出重叠的部分