References: 1. http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html
2 . https://www.cnblogs.com/hadilo/p/5914302.html
1. Euclidean algorithm (the focus is on proof, useful for subsequent knowledge)
Euclidean Algorithm, also called division by turn, or gcd for short, is used to calculate the greatest common divisor of two integers
Define gcd(a,b) as the greatest common divisor of integers a and b
Lemma: gcd(a,b)=gcd(b,a%b)
Prove:
设 r=a%b , c=gcd(a,b)
Then a=xc , b=yc , where x , y are relatively prime
r=a%b=a-pb=xc-pyc=(x-py)c
while b=yc
It can be seen that y and x-py are relatively prime
Prove:
Suppose y is not coprime to x-py
Let y=nk , x-py=mk , and k>1 (because of coprime)
Bring y to get
x-pnk=mk
x=(pn+m)k
则 a = xc = (pn + m) kc, b = yc = nkc
Then the greatest common divisor of a and b at this time is kc not k
Contradicting with the original proposition, then y and x-py are relatively prime
Since y and x-py are relatively prime, the greatest common divisor of r and b is c
即 gcd(b,r)=c=gcd(a,b)
certified
When a%b=0, gcd(a,b)=b
Recursive algorithm:
int gcd(int a,int b) { if(b==0) return a; return gcd(b,a%b); }
optimization:
int gcd(int a,int b) { return b ? gcd(b,a%b) : a; }
2. Extended Euclidean Algorithm
Extended Euclidean algorithm, referred to as exgcd, is generally used to solve indefinite equations, solve linear congruence equations, solve inverse elements of modules, etc.
Lemma: there exists x , y such that gcd(a,b)=ax+by
Prove:
When b=0, gcd(a,b)=a, then x=1, y=0
When b!=0,
设 ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(a%b)y2
Also cause a% b = aa / b * b
Then ax1+by1=bx2+(aa/b*b)y2
ax1+by1=bx2+ay2-a/b*by2
ax1+by1=ay2+bx2-b*a/b*y2
ax1+by1=ay2+b(x2-a/b*y2)
Solve x1=y2 , y1=x2-a/b*y2
Because x exists when b=0, y is the last set of solutions
And the solution of each group can be obtained according to the latter group
So the first set of solutions x , y must exist
certified
According to the above proof, the recursive approach is used in the implementation
First recursively enter the next layer, and return x=1, y=0 when reaching the last layer, that is, b=0
Then according to x=y' , y=x'-a/b/y' ( x' and y' are the x and y of the next layer) to get the solution of the current layer
Continue to calculate the solution of the current layer and return, and finally return to the first layer to get the original solution
int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } int r=exgcd(b,a%b,x,y); int t=x; x = y; y=t-a/b*y; return r; }
The application of extended Euclidean algorithm mainly has the following three aspects:
(1) Solve the indefinite equation;
(2) Solve the modular linear equation (linear congruence equation);
(3) Solve the inverse of the module;
( 1 ) exgcd solves indeterminate equations (using a method that does not convert a and b to coprime)
For the indefinite equation of ax+by=c, let r=gcd(a,b)
No integer solution when c%r!=0
When c%r=0, convert the right side of the equation *r/c to ax+by=r
A set of integer solutions x0 , y0 can be obtained according to the extended Euclidean algorithm
And this is just the solution of the transformed equation, the set of solutions of the original equation should be transformed back by *c/r
(For example, after converting 2x+4y=4 to 2x+4y=2, multiply the obtained x and y by 2)
Then the original equation is solved as x1=x0*c/r , y1=x0*c/r
General solution x=x1+b/r*t , y=y1-a/r*t , where t is an integer
Prove:
Put x , y into the equation to get
ax+ab/r*t+by-ab/r*t=c
ax+by=c
This equation always holds
certified
Here b/r and a/r are the smallest coefficients, so the obtained solution is the most comprehensive
Prove:
In order to deduce ax+by=c in the proof, and to achieve a smaller coefficient, we can only divide b/r and a/r by a number s
And b/r and a/r are relatively prime, and s is an integer, then s=1, which does not affect the general solution
Then b/r and a/r are the smallest coefficients
certified
bool linear_equation(int a,int b,int c,int &x,int &y) { int d=exgcd(a,b,x,y); if(c%d) return false; int k=c/d; x *=k; y*=k; // Only one set of solutions is obtained return true ; }
will expand further. . . . Looking forward to it!