Discrete Logging
Time Limit: 5000MS |
|
Memory Limit: 65536K |
Total Submissions: 6683 |
|
Accepted: 2963 |
Description Given a prime p, 2 <= p < 2, an integer B, 2 <= B < P, and an integer n, 1 <= n < P, comp Ute the discrete logarithm of N, base B, modulo P. That's, 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 to a separate line. If There is 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's probably expected of you for Putna m but 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
BSGS algorithm: Full baby-step-giant-step, the smallest integer solution (x>=0) for solving equations such as a^x=b (mod p).
When P is a prime number, it can be solved by BSGS algorithm.
Solution Method:
If A and p are not coprime, then there is no solution.
Find out M=ceil (sqrt (p)), make x=i*m-j.
(a^m) ^i=a^j*b (mod p)
Enumerates j = 0..m and a^j*b into a hash table.
Enumeration i = 1..M, when the smallest I is taken to make the above equation set up, then x min = i*m-j.
You can use the Extended BSGS algorithm when p is not a prime number.
#include <cstdio> #include <iostream> #include <string.h> #include <string> #include <map > #include <queue> #include <deque> #include <vector> #include <set> #include <algorithm&
Gt #include <math.h> #include <cmath> #include <stack> #include <iomanip> #define MEM0 (a) memset (a)
0,sizeof (a)) #define Meminf (a) memset (A,0x3f,sizeof (a)) using namespace Std;
typedef long Long LL;
typedef long double LD;
typedef double DB;
const int inf=0x3f3f3f3f;
const LL LLINF=0X3F3F3F3F3F3F3F3F;
Const LD Pi=acos ( -1.0L);
Map<ll,int> MP;
ll Fastpower (ll base,ll index,ll MoD) {ll ans,now;
if (index<0) return 1;
Ans=1;
Now=base;
ll K=index;
while (k) {if (k%2) Ans=ans*now;
Ans%=mod;
Now=now*now;
Now%=mod;
k/=2;
} return ans;
} ll Bsgs (ll a,ll b,ll p) {int i;
if (p%a==0) return-1;
if (p==1) return 0;
ll M=ceil (sqrt (p));
ll L=b;
Mp[l]=1;
for (i=1;i<=m;i++) {l*=a;
L%=p; Mp[l]=i+1;
} l=fastpower (a,m,p); ll R=l;
for (i=1;i<=m;i++) {if (Mp[r]) {ll ans=i*m-mp[r]+1;
Mp.clear ();
return ans;
} r*=l;
R%=p;
} mp.clear ();
return-1;
} int main () {ll p,b,n;
while (scanf ("%lld%lld%lld", &p,&b,&n)!=eof) {ll ans=bsgs (b,n,p); if (ans==-1) printf ("No solution\n");
else printf ("%lld\n", ans);
} return 0; }