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

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)
BSGS算法模板
Navi拿了一张截图
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 typedef long long lol;
 8 int MOD=250000;
 9 lol hash[300001],id[300001];
10 void insert(lol x,lol d)
11 {
12   lol pos=x%MOD;
13   while (1)
14     {
15       if (hash[pos]==-1||hash[pos]==x)
16     {
17       hash[pos]=x;
18       id[pos]=d;
19       return;
20     }
21       pos++;
22       if (pos>=MOD) pos-=MOD;
23     }
24 }
25 bool count(lol x)
26 {
27   lol pos=x%MOD;
28   while (1)
29     {
30       if (hash[pos]==-1) return 0;
31       if (hash[pos]==x) return 1;
32       pos++;
33       if (pos>=MOD) pos-=MOD;
34     }
35 }
36 lol query(lol x)
37 {
38   lol pos=x%MOD;
39   while (1)
40     {
41       if (hash[pos]==x) return id[pos];
42       pos++;
43       if (pos>=MOD) pos-=MOD;
44     }
45 }
46 lol qpow(lol x,lol y,lol Mod)
47 {
48   lol res=1;
49   while (y)
50     {
51       if (y&1) res=res*x%Mod;
52       x=x*x%Mod;
53       y>>=1;
54     }
55   return res;
56 }
57 lol BSGS(lol a,lol b,lol Mod)
58 {int i;
59   memset(hash,-1,sizeof(hash));
60   memset(id,0,sizeof(id));
61   lol tim=ceil(sqrt((double)Mod));
62   lol tmp=b%Mod;
63   for (i=0;i<=tim;i++)
64     {
65       insert(tmp,i);
66       tmp=tmp*a%Mod;
67     }
68   lol t=tmp=qpow(a,tim,Mod);
69   for (i=1;i<=tim;i++)
70     {
71       if (count(tmp))
72     return i*tim-query(tmp);
73       tmp=tmp*t%Mod;
74     }
75   return -1;
76 }
77 int main()
78 {lol p,a,b,ans;
79   while (~scanf("%lld%lld%lld",&p,&a,&b))
80     {
81       if ((ans=BSGS(a,b,p))==-1) printf("no solution\n");
82       else printf("%lld\n",ans);
83     }
84 }

 

posted @ 2018-02-04 10:29  Z-Y-Y-S  阅读(200)  评论(0编辑  收藏  举报