Consider a problem: a^x%p=b, given the a,b,p, the minimum nonnegative integer solution of x is obtained.
In the case of P being prime, the problem is relatively simple.
a^x=b (mod p) (p is A Prime, a,b<p) Let m = Floor (sqrt (P)) Put a^0,a^1,... a^ (m-1) to HashSet (you Can Also with Map in STL), for Example m[a^i]=i.
If A^i=a^j (i<j), m[a^i=a^j]=i.
enumerate I, let X=i*m+j, a^ (i*m) *a^j=b (mod C) Let e=a^ (i*m), f=a^j,e*f=b (mod P) because (e,c) =1, (e,c) | B,we can use EXTGCD to get F.
If F is in the Hashset,then the minimum answer x=i*m+m[f].
Then if a answer exists, the minimum answer must and then P.
The range of I is [0,p/m].
If for all I we cannot find a answer and then no solution.
I personally write the things, can understand only strange!
Just attach the code: (My small data range is violent)
#include <cmath> #include <cstdio> #include <cctype> #include <cstring> #include <iostream > #include <algorithm>using namespace std;typedef long long ll;inline void exgcd (ll A, ll B, LL &d, LL &x, LL &y) {if (!b) {d = a, x = 1, y = 0;} else {EXGCD (b, a% B, D, y, x), Y-= x * (A/b);}} inline ll gcd (ll A, ll b) {return (!b) A:GCD (b, a% b);} inline ll Solve (ll A, ll B, ll c) {//ax=b (mod c) LL D, X, y; EXGCD (A, C, D, X, y); return (x + c)% c * b% c;} ll KSM (ll X, ll y, ll P) {ll res = 1, t = x;for (; y; y >>= 1) {if (Y & 1) res = res * t% p;t = t * t% P;} return res;} const int mod = 13131;struct Hashset {int head[mod], next[40010], f[40010], v[40010], ind;void Reset () {ind = 0;memset (hea D,-1, sizeof head);} void Insert (int x, int _v) {int ins = x% mod;for (int j = Head[ins]; J! =-1; j = Next[j]) if (f[j] = = x) {V[j] = min (V[j], _V); return;} F[ind] = x, v[ind] = _v;next[ind] = Head[ins], head[ins] = ind++;} int operator [] (const INT &x) const {int ins = x% mod;for (int j = Head[ins]; J! =-1; j = Next[j]) if (f[j] = = x) return v[j];return-1;}} S;int Main () {LL A, B, C; ll I;while (scanf ("%i64d%i64d%i64d", &c, &a, &b) = = 3) {if (C <=) {LL d = 1;bool find = 0;for (i = 0; I & Lt C ++i) {if (d = = B) {find = 1;printf ("%i64d\n", I); break;} D = d * A% C;} if (!find) puts ("no solution");} else {int m = (int) sqrt (C); S.reset (); LL d = 1;for (i = 0; i < m; ++i) {S.insert (d, i);d = d * A% C;} bool find = 0;int ins;for (i = 0; I * m < C; ++i) {LL t = Solve (KSM (A, I * m, c), B, C), if ((INS = s[t])! =-1) {printf ( "%i64d\n", I * m + ins); find = 1;break;}} if (!find) puts ("no solution");}} return 0;}
POJ2417 Baby-step-gaint-step algorithm