Euclidean method (Euclid algorithm)
Time complexity: Within O (LogMax (A, B))
int gcd (int a, int b) {if (b = = 0) return A;return gcd (b, a% b);}
Extended Euclidean algorithm
The complexity of time is the same as Euclid's algorithm.
int extgcd (int a, int b, int& x, int& y) {int d = a;if (b! = 0) {d = EXTGCD (b, a% B, y, x); y-= (A/b) * x;} else {x = 1; y = 0;} return D;}
For AX+BY=GCD (A, b) integer solution, XY returns an integer solution, and the return value of EXTGCD is the value of Ax+by.
Title: (a+x*c)%2^k=b x Integer solution.
Analytical:
The integer solution of x*c=b-a in mod (2^k) case
The solution that can be converted into x*c+y* (2^k) =b-a
The solution x1,y1,d=x1*c+y1* (2^k) =GCD (c,2^k) of x1*c+y1* (2^k) =GCD (c,2^k) was obtained by extending Euclidean algorithm.
X1*c+y1* (2^k) = (b-a) (GCD (c,2^k)/(B-A))
(A-B)/gcd (c,2^k) *x1*c+ (A-B)/gcd (c,2^k) *y1* (2^k) =b-a
X= (A-B)/gcd (c,2^k) *x1
Y= (A-B)/gcd (c,2^k) *y1
The required value is x,x, which may be negative, so change the x to a positive integer. Change to a positive number by + (2^K)/d and% (2^K)/d.
#include <cstdio>long long extgcd (long long A, long long B, long long& x, long long& y) {long Long d = a;if ( b! = 0) {d = EXTGCD (b, a% B, y, x); y-= (A/b) * x;} else {x = 1; y = 0;} return D;} int main () { Long long A, B, C, K; while (scanf ("%lld%lld%lld%lld", &a, &b, &c, &k)! = EOF) { if (a = = 0 && b = = 0 && c = = 0 && k = = 0) break; Long long x, y; Long Long t = b-a; Long long H = 1LL << k; 2^k long Long g = EXTGCD (c, h, X, y); if (t% g! = 0) {//no solution printf ("forever\n"); Continue; } x *= t/g; x = (x% (h/g) + (h/g))% (h/g);//minimum nonnegative integer solution printf ("%lld\n", x); } return 0;}
POJ 2115 C looooops (Extended Euclid)