Http://poj.org/problem? Id = 2417
A ^ x = B (mod c). We know A, B, C, and X.
Here, C is a prime number, which can be a common baby_step.
In the process of finding the smallest X, set X to I * m + J. Then the original value becomes a ^ m ^ I * a ^ J = B (mod C), D = a ^ m, then d ^ I * a ^ J = B (mod C ),
Store a ^ J in the hash table in advance, and then enumerate I (0 ~ M-1), according to the Extended Euclidean get a ^ J, and then go to the hash table to find the corresponding J, then x = I * m + J.
Determine whether X has a solution, that is, to judge whether a ^ J has a solution when looping I, and the minimum solution x must be (0 ~ C-1) Because gcd (d ^ I, c) = 1.
If (0 ~ C-1) no solution, so 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, cycle section length is PHI (c), that is, C-1, x> = C after starting a new round of cycle, therefore (0 ~ C-1) in the case of no solution, 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 # 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 a hash table Void insert (int id, ll vv) {int v = VV % maxn; while (hash [v] & Val [v]! = Vv) {v ++; If (V = maxn) V-= maxn;} If (! Hash [v]) {hash [v] = true; idx [v] = ID; Val [v] = VV ;}// find the jj corresponding to VV, 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 formula becomes a ^ m ^ I * a ^ J = B (mod c) First enumeration J (0 ~ M-1), save a ^ J % C into the hash table so that D = a ^ m % C, x = a ^ J, then d ^ I * x = B (mod C) enumeration I (0 ~ M-1) to obtain d ^ I set to DD, DD * x = B (mod c) dd, C known, according to the Extended Euclidean get X, in the hash table to find x corresponding JJ, that is, a ^ JJ = x. Then X = I * m + JJ. If no JJ is found, no solution is available. */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); // save a ^ J to 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 X in the equation res * x = B (mod C), and find the JJ corresponding to X, 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) {return (LL) I * m + JJ;} res = res * D % C;} return-1;} int main () {ll A, B, c; while (~ Scanf ("% LLD", & C, & A, & B) {ll res = baby_step (A, B, C ); if (RES =-1) printf ("no solution \ n"); elseprintf ("% LLD \ n", Res) ;}return 0 ;}