欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:gcd(a,b)=gcd(a,a mod b)
gcd函数就是用来求(a,b)的最大公约数的。
设d为a,b的公约数,则有 d|a,d|b d | a , d | b
设 r=amodb=a−⌊ab⌋b r = a mod b = a − ⌊ a b ⌋ b
所以d|r
即(a,b)的公约数是(b,a mod b)的公约数
设d’为b, a mod b 的公约数,则 d′|b,d′|(amodb) d ′ | b , d ′ | ( a mod b )
因为 a=r+⌊ab⌋b a = r + ⌊ a b ⌋ b
所以 d′|a d ′ | a
即(b,a mod b)的公约数是的(a,b)公约数
所以(b,a mod b),(a,b)公约数相同,其最大公约数也相同
int gcd(int a,int b) {
int c;
while (b!=0) {
c=a%b;a=b;b=c;
}
return a;
}
扩展欧几里德算法是用来在已知a, b求解一组x,y,使它们满足贝祖等式: ax+by = gcd(a, b) =d(解一定存在,根据裴蜀定理)。扩展欧几里德常用在求解模线性方程及方程组中。
设 a>b a > b
当 b=0,gcd(a,b)=a b = 0 , g c d ( a , b ) = a 所以此时 x=1,y=0 x = 1 , y = 0 ;
当 a>b>0 a > b > 0 时
设 ax1+by1=gcd(a,b),bx2+(amodb)y2=gcd(b,amodb); a x 1 + b y 1 = g c d ( a , b ) , b x 2 + ( a mod b ) y 2 = g c d ( b , a mod b ) ;
根据朴素的欧几里德原理有 gcd(a,b) = gcd(b,a mod b);
则 ax1+by1=bx2+(amodb)y2 a x 1 + b y 1 = b x 2 + ( a mod b ) y 2 ;
即 ax1+by1=bx2+(a−⌊ab⌋×b)y2=ay2+bx2−⌊ab⌋×by2 a x 1 + b y 1 = b x 2 + ( a − ⌊ a b ⌋ × b ) y 2 = a y 2 + b x 2 − ⌊ a b ⌋ × b y 2 ;
根据恒等定理得: x1=y2,y1=x2−⌊ab⌋×y2 x 1 = y 2 , y 1 = x 2 − ⌊ a b ⌋ × y 2
恒等定理:两个多项式相等,则这两多项式最高次数相同,且对应次数项的系数相同.
通过递归我们可以不断的推出x1,y1,最终达到求解ax+by=gcd(a,b)的目的。
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 z=x;
x=y;y=z-a/b*y;
return r;
}
扩展欧几里得的应用主要有三个方面:
求解不定方程ax+by=c
用扩展gcd求出 ax′+by′=gcd(a,b) a x ′ + b y ′ = g c d ( a , b ) 的解 x′,y′ x ′ , y ′
x′,y′ x ′ , y ′ 分别乘上 c/gcd(a,b) c / g c d ( a , b ) 则可得到ax+by=c的一组解x,y;
当 cmodgcd(a,b)≠0 c mod g c d ( a , b ) ≠ 0 方程无解
如何求通解?
设 x=x0+p,y=y0−q x = x 0 + p , y = y 0 − q ( x0,y0 x 0 , y 0 为上述过程中解出的特解x,y),且 a(x0+p)+b(y0−q)=c a ( x 0 + p ) + b ( y 0 − q ) = c .
可得 ap=bq a p = b q .
又因为 a(x0+p)+b(y0−q)=c a ( x 0 + p ) + b ( y 0 − q ) = c
所以p,q应为a,b的公倍数
那么我们可以得到
所以得到通解
因为 lcm(a,b)=abgcd(a,b) l c m ( a , b ) = a b g c d ( a , b )
所以当 lcm(a,b) l c m ( a , b ) 过大时,我们可以将 lcm(a,b)a l c m ( a , b ) a 变为 bgcd(a,b) b g c d ( a , b )
求解:
即
使用前文的方法解 ax+my=b a x + m y = b 即可
有 ax≡1(modm) a x ≡ 1 ( mod m )
同2可得 ax+my=1 a x + m y = 1
解出x即为a的逆元
jzoj 1158. 荒岛野人
jzoj 3909. 【NOIP2014模拟11.1A组】Idiot 的乘幂