Need to solve the problem before, first to do POJ2417, my method of solving the problem: http://blog.csdn.net/wyfcyx_forever/article/details/40538515
Now look at this question: A x ≡B(mod C )
Known a,b,c<=10^9, given a,b,c, the smallest integer solution of x is obtained.
Note that there is no limit to the a,b,c here!
Then consider why our traditional GSBs algorithm does not solve the problem: If an enumeration of I, we have to use the expansion of Euclid to find out that there is no one a^j (0<=j<m), so that a^ (i*m) *a*j%c=b.
So a^j=x, what we're actually asking for is an integer solution of a two-tuple equation: a^ (i*m) x+cy=b. We know that there are solutions and only if GCD (a,c) | B, however, there is no limit at this moment, which is clearly not necessarily satisfactory.
We're going to make some changes to the algorithm. So that it can do the above processing. Detailed proof to see the aekdycoin Ben of the puzzle, I am simply to explain my understanding.
The beginning equation is equivalent to A^x*a+c*b=b (A, B is an integer). Now GCD (a,c)!=1, it is best to make T=GCD (A,C)
We consider the equation (A/T) a^x '% (c/t) = (b/t) of the solution X ' in relation to the original solution x.
Obviously today's equation is equivalent to (A/T) a^x ' *a ' + (c/t) *b ' =b/t.
Both ends are multiplied by T to get: a^ (x ' + 1) *a ' +c*b ' =b
are equal by coefficients: x=x ' +1,a=a ', b=b '.
Then we have a way to figure out X. Calculate the X ' first, plus 1.
Considering how to find X ', the equation now assumes that a,c is still not coprime and continues to iterate to divide the coefficients by greatest common divisor. The constants in front of the same time increase.
Then we can find out the solution and add the total number of times.
Code:
#include <cmath> #include <cstdio> #include <cctype> #include <cstring> #include <climits > #include <iostream> #include <algorithm>using namespace Std;typedef long Long Ll;inline ll gcd (ll A, LL b) {return (!b)? A:GCD (b, a% b);} 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 Solve (ll A, ll B, ll c) {//Ax%c=b s.t. (a,c) =1ll D, X, y; EXGCD (A, C, D, X, y); x = (x + c)% c;return x * b% c;} inline 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;} #define MOD 1313131struct Hashset {int head[mod], next[35010], f[35010], v[35010], ind;void Reset () {ind = 0;memset (Head, -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) retu RN v[j];return-1;}} S ll Bsgs (ll C, LL A, LL B, ll p) {//A^x%p=b s.t. (a,p) =1if (P <=) {LL d = 1;for (int i = 0; i < P; ++i) {if (d = = B) Return i;d = d * A% p;} return-1;} else {int m = (int) sqrt (p); S.reset (); LL d = 1, search;for (int i = 0; i < m; ++i) {S.insert (d, i);d = d * A% p;} for (int i = 0; I * m < p; ++i) {d = Ksm (A, I * m, p) * C% P; Search = S[solve (d, B, p)];if (Search! =-1) return I * m + Search;} return-1;}} int main () {ll x, Z, K;register ll I, J;while (scanf ("%i64d%i64d%i64d", &x, &z, &k) = = 3 && (x + z + k) {LL d = 1;bool find = 0;for (i = 0; i <; ++i) {if (d = = k) {printf ("%i64d\n", i); find = 1;break;} D = d * x% Z;} if (find) continue; LL T, C = 1, num = 0;bool failed = 0;while ((t = gcd (x, z))! = 1) {if (k% t! = 0) {failed = 1;break;} Z/= t;k/= t; c = c * x/t% Z;++num;} if (failed) {puts ("NoSolution "); continue;} LL res = BSGS (C, X, K, z), if (res = =-1) puts ("No solution"), elseprintf ("%i64d\n", res + num);} return 0;}
Copyright notice: This article blog original article. Blogs, without consent, may not be reproduced.
POJ3243 EXT-BSGS algorithm