http://poj.org/problem?id=2417
a^x = B (mod C), known as a, a. C. Find X.
Here c is a prime number and can be used with ordinary baby_step.
In the process of finding the smallest x, set X to I*m+j. The original becomes a^m^i * a^j = b (mod c), D = A^m, then d^i * a^j = b (mod c),
Pre-a^j into the hash table, and then enumerate I (0~m-1), according to the expansion of Euclid to find out a^j. Then go to the hash table to find the corresponding J, then x = I*m+j.
Determine if x has a solution, which is to infer whether the corresponding a^j has a solution at the time of loop i. Also the smallest solution x must be in (0~c-1), in that gcd (d^i,c) = 1.
Assuming (0~c-1) no solution, then there must be no solution.
Because A^x%c (C is a prime number) has a cyclic section. a^x%c = a^ (X%phi[c])%c, the length of the loop is Phi (c), that is, c-1,x >= C starts a new round of loops, so there is no solution in (0~c-1). There must be no solution.
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <list># Include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue># Include <string> #include <stdlib.h> #include <algorithm> #define LL long long#define _ll __int64# Define EPS 1e-12#define PI acos ( -1.0) using namespace std;const int maxn = 499991;bool Hash[maxn+10];int idx[maxn+10]; ll val[maxn+10];//insert hash table void Insert (int id, LL vv) {int v = vv% maxn;while (Hash[v] && val[v]! = VV) {v++;if (v = = max N) v-= MAXN;} if (!hash[v]) {Hash[v] = true;idx[v] = id;val[v] = VV;}} Find VV corresponding JJ,A^JJ = Vvint found (LL vv) {int v = vv%maxn;while (Hash[v] && val[v]! = VV) {v++;if (v = = MAXN) v-= MAXN;} if (hash[v] = = False) Return-1;return idx[v];} void Extend_gcd (ll A, ll B, LL &x, ll &y) {if (b = = 0) {x = 1;y = 0;return;} EXTEND_GCD (B,a%b,x,y); LL t = x;x = Y;y = T-a/b*y;} /*a^x = B (mod C) Order x = I*m+j, where M = Ceil (sqrt (c*1.0)), (0 <= I,j < M) then the original becomes a^m^i*a^j = b (mod c) First enumerates J (0~m-1), the a^j%c is stored in the hash table so that d = a^m%c,x = A^j, then d^i*x = B (mod c) enumeration I (0~M-1) evaluates to D^i set to DD 。 dd*x = B (mod C) dd,c known, because C is a prime number, gcd (dd,c) = 1, according to the extension Euclid learned that there is only one solution X in [0,c-1]. Then find the x corresponding JJ in the hash table. That is A^JJ = X.So x = I*M+JJ, if you can't find JJ no solution. */ll Baby_step (ll A, LL B, ll C) {memset (hash,false,sizeof (hash)); memset (idx,-1,sizeof (IDX)); Memset (Val,-1,sizeof (val )); ll M = ceil (sqrt (c*1.0));//The a^j is stored in the hash table ll D = 1;for (int j = 0; J < M; J + +) {Insert (j,d);D = d*a%c;} D = A^m%c,res = D^i, find the x in equation res*x = B (mod C), go to x corresponding JJ, then X=I*M+JJ. LL res = 1,x,y;for (int i = 0; i < M; i++) {EXTEND_GCD (res,c,x,y); x = X*b;x = (x%c+c)%c;int JJ = Found (x); if (JJ! =-1) {RE Turn (LL) i*m+jj;} res = res*d%c;} return-1;} int main () {ll a,b,c;while (~scanf ("%lld%lld%lld", &c,&a,&b)) {ll res = Baby_step (a,b,c); if (res = =-1) printf ( "No solution\n"); elseprintf ("%lld\n", res);} return 0;}
POJ 2417 Discrete Logging (a^x=b (mod c), General Baby_step)