Discrete Logging
Time Limit: 5000MS |
|
Memory Limit: 65536K |
Total Submissions: 4236 |
|
Accepted: 1948 |
Description Given a prime P, 2 <= p < 231, an integer B, 2 <= B < P, and an integer n, 1 <= n < P, compute the DISCR Ete 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 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 in number theory that's probably expected of you for Putnam 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 |
Naked Bsgs.
B^l=b^k1*b^k2
Known b^k1 hash b^k2 complexity O (sqrt (f) *hash (f)) hash (f) for the complexity of the hash
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include < functional> #include <iostream> #include <cmath> #include <cctype> #include <ctime>using namespace std; #define for (I,n) for (int. i=1;i<=n;i++) #define FORK (I,k,n) for (int. i=k;i<=n;i++) #define REP (I,n) for (int i=0;i<n;i++) #define ForD (I,n) for (int. i=n;i;i--) #define REPD (I,n) for (int. i=n;i>=0;i--) #define FORP (x) for ( int p=pre[x];p; p=next[p]) #define FORPITER (x) for (int &p=iter[x];p; p=next[p]) #define LSON (x<<1) #define Rson ((x<<1) +1) #define MEM (a) memset (A,0,sizeof (a)), #define MEMI (a) memset (A,127,sizeof (a)), #define MEMI (a) memset ( A,128,sizeof (a)); #define INF (2139062143) #define F (100000007) #define MAXN (1000000) typedef long Long Ll;ll Mul (ll A,ll b) {return (a*b)%F;} ll Add (ll A,ll b) {return (a+b)%F;} ll Sub (ll A,ll b) {return (a-b+ (a)/f*f+f)%F; void Upd (ll &a,ll b) {a= (a%f+b%f)%F;} Char s[]= "No solution\n"; class Math{public:ll gcd (ll A, ll b) {if (!b) return A;return gcd (b,a%b);} ll ABS (ll x) {if (x>=0) return x;return-x;} ll exgcd (ll A,ll b,ll &x, ll &y) {if (!b) {X=1,y=0;return A; } ll G=EXGCD (b,a%b,x,y); ll T=x;x=y;y=t-a/b*y; return g; } ll Pow2 (ll a,int b,ll p) {if (b==0) return 1; if (b==1) return A; ll C=pow2 (a,b/2,p); c=c*c%p; if (b&1) c=c*a%p; return C; } ll MODP (ll a,ll b,ll p) {ll x, y; ll G=EXGCD (a,p,x,y), D; if (b%g) {return-1;} D=b/g;x*=d,y*=d; X= (X+abs (x)/p*p+p)%p; return x; } int H[MAXN]; ll HNUM[MAXN]; int hash (ll x) {int i=x%maxn; while (h[i]&&hnum[i]!=x) i= (i+1)%MAXN; Hnum[i]=x; return i;} ll Babystep (ll a,ll b,int p) {MEM (h) MEM (hnum) int m=sqrt (p); while (m*m<p) m++; ll Res=b,ans=-1; ll Uni=pow2 (a,m,p); if (!uni) if (!b) Ans=1;else ans=-1; Special Award for else {REP (i,m+1) {int T=hash (res); h[t]=i+1; Res= (res*a)%p; } Res=uni; for (i,m+1) {int T=hash (res); if (H[t]) {ans=i*m-(h[t]-1); break;} else hnum[t]=0; res=res*uni%p; }} return ans; }}s;int Main () {//freopen ("poj2471.in", "R", stdin),//freopen (". Out", "w", stdout); ll P,b,n;while (cin>>p> >b>>n) {ll ans=s.babystep (b,n,p); if (ans==-1) Cout<<s;else Cout<<ans<<endl;} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
POJ 2417/bzoj 3239 (discrete logging-bsgs) [Template: Number theory]