Euclidean algorithm:
Euclidean algorithm, also known as flounder division, referred to gcd, used to calculate the greatest common divisor of two integers
Principle: Euclidean algorithm to solve the greatest common divisor (common factor)
Provided two atoms a, b (a> b), with the GCD (a, b) represents a, b greatest common divisor
r = a (mod b) () is the remainder of a divided by b, q is a quotient divided by b, i.e. a ÷ b = q ....... r. Euclidean i.e. to prove gcd (a, b) = gcd (b, r).
Proved that: a / b = q; a = q * b + r;
<1> when r = 0 when, b is the greatest common divisor of a and b
<2> when r = 0, the! Set a, b is the greatest common divisor c, a = m * c; b = n * c; ( c is because a, b greatest common divisor, the m, n mutually quality)
r = aq * b; r = (m * c) -q * b (n * c) = (mq * b * n) * c, a divisor can be seen also c of r,
So we can continue to b / r 0 r until we come to a, b is the greatest common divisor
Recursion:
#include<iostream> using namespace std; int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); } int main () { int a, b, years; cin>>a>>b; years = gcd (a, b); cout << years; return 0 ; }
optimization:
#include<iostream> using namespace std; int gcd(int a,int b){ return b?gcd(b,a%b):a; } int main () { int a, b, years; cin>>a>>b; years = gcd (a, b); cout << years; return 0 ; }
Extended Euclidean Algorithm:
Extended Euclidean Algorithm, referred exgcd, generally used to solve the equation, solving the linear congruence equations, solving the inverse mode, and the like
Extended Euclidean Algorithm: find a * x + b * y = c in the general solution.
Pei Shu theorem: for integers a, b, they are about x, y linear indeterminate equation A X + B Y = D AX + by = D, provided G C D ( A , B ) = G GCD (A, B) = g,
May prove g | D g | D, in other words, g is the minimum linear combination of a, b of
prove:
. Provided a * x + b * y = t,
<1> When b = 0, t = a (because gcd algorithm, if (b == 0) return a;), there are a * x = a, easy to get x = 1.
<2> When b = 0, the! Set a * x1 + b * y1 = gcd (a, b), b * x2 + (a% b) * y2 = gcd (b, a% b); Because gcd (a , b) = gcd (b, a% b), there is simultaneous: a * x1 + b * y1 = b * x2 + (a% b) * y2.
a% b = a- (a / b) * b; (a / b direction trade integer).
The 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 for x1 = y2, y1 = x2-a / b * y2
The proof of the above, the recursive approach in the realization of the recursive into the first layer, i.e., until reach the last layer when b = 0 returns x = 1, y = 0
Then according to x = y ', y = x'-a / b / y' (x 'and y' and the next layer in the x y) obtained when a layer of solution. When the solution is calculated continuously and return layer, eventually returned to the first layer, to obtain 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; }
Euclid expand inversion yuan
PS: a ≡ b (mod m) 读作a同余于b模m,或读作a与b关于模m同余。 比如 26 ≡ 14 (mod 12)。
什么是逆元?a∗x≡1 (mod m) ,这里x就是a的逆元。逆元有什么用呢?如果我们要求a/b mod m的值,而a,b很大,设b的逆元为x,
这个时候注意到(a/b)∗x∗b=(a/b) mod m= a ∗ x mod m巧妙地把出发转换成了乘法。
为什没求逆元跟欧几里得算法联系起来了呢?根据上面裴蜀定理,我们知道gcd是a,b两个数线性组合的最小值,其他组合值都是gcd的倍数,
当gcd为1时,a,b互质,满足ax+by=1ax+by=1,移项得ax=−by+1,即ax≡1 mod b ,此时的x就是逆元。实际上线性不定方程组有无穷多解,这里只求正的最小的逆元。
int cal(int a,int m) { int x,y; int gcd = ex_gcd(a,m,x,y); //cout << "a " << a << " m " << m << " x " << x << " y " << y << endl; if(1%gcd!=0) return -1; x*=1/gcd; m = abs(m); int ans = x%m; if(ans<=0) ans += m; return ans; }
这里1%gcd是看gcd是不是1,前面说了,d(这里是1)应该是gcd的倍数,而且不互质的两个数没有逆元。
x∗=1/gcdx∗=1/gcd实际上更一般的写为x∗=d/gcdx∗=d/gcd,也就是求解一般不定方程ax+by=dax+by=d的解,因为d是gcd的倍数,我们就把倍数乘上去解得x′=x∗(d/gcd)x′=x∗(d/gcd)。
m是负数的话,我们取|m|,如果求出来x是负数,就x%|m|,结果再加上|m|即可。(因为有无穷个解,通解为x+m∗tx+m∗t)