Time Limit: 5000MS |
|
Memory Limit: 65536KB |
|
64bit IO Format: %i64d &%i64u |
Description
Given a prime p, 2 <= p < 2, an integer B, 2 <= B < P, and an integer n, 1 <= N < P, compute the Discrete logarithm of N, base B, modulo P. That's, 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 to a separate line. If There is several, print the smallest; If there is none, print "no solution".
Sample Input
5 2 15 2 25 2 35 2 45 3 15 3 25 3 35 3 45 4 15 4 25 4 35 4 412345701 2 11111111111111121 65537 1111111111
Sample Output
013203120no Solutionno solution19584351462803587
Hint
The solution to this problem requires a well known result on number theory that's probably expected of you for Putnam But is not ACM competitions. It's 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, is pseudoprimes for every base between 2 and P-1. A corollary to Fermat's theorem is the for any m
B
(-M)
= = B
(p-1-m)
(mod P).
Source
Waterloo Local 2002.01.26
The formula is this: BL = = N (mod P) to find the smallest L
Decompose L: l=i*m+j where M=SQRT (P) is rounded up
Native to b^ (i*m) *b^j==n (MOD P)
Re-translated into b^j===n*b^ (-i*m) (MOD P)
First preprocess the b^1 b^2 ... b^ (m-1)
After the B^-M, enumeration I, if the existence of b^ (-I*M) exists in the hash table, indicating the existence of a solution l=i*m+j
In fact, I don't know much about 2333.
The code basically relies on copying
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6 using namespacestd;7 Const intmop=100007;8 intHash[mop];9 inthead[mop],nxt[mop],id[mop],cnt;Ten voidAddintXintY) {//Hash One intm=x%Mop; Ahash[++cnt]=x;nxt[cnt]=head[m];id[cnt]=y;head[m]=CNT; - return; - } the intFindintx) { - intm=x%Mop; - inti,j; - for(i=head[m];i!=-1; i=Nxt[i]) { + if(hash[i]==x)returnId[i]; - } + return-1; A } at intBSGS (intAintBintN) {//a^x mod n =b -memset (head,-1,sizeofhead); -Cnt=0; - if(b==1)return 0; - intM=sqrt ((Double) n), J; - Long Longx=1, p=1; in for(intI=0; i<m;i++,p=p*a%n) Add (p*b%n,i);//pretreatment b^i - for(Long Longi=m; i+=.L) { tox=x*p%N; + if((J=find (x))!=-1)returnI-J; - if(i>n) Break; the } * return-1; $ }Panax Notoginseng intMain () { - intP,b,n; the while(SCANF ("%d%d%d", &p,&b,&n)! =EOF) { + intans=bsgs (b,n,p); A if(ans==-1) printf ("No solution\n");//No solution the Elseprintf"%d\n", ans); + } - return 0; $}
POJ 2417 Discrete Logging