扩展欧几里得及其应用

欧几里得算法

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:gcd(a,b)=gcd(a,a mod b)
gcd函数就是用来求(a,b)的最大公约数的。


证明gcd(a,b)=gcd(a,a mod b)

设d为a,b的公约数,则有 d|a,d|b d | a , d | b
r=amodb=aabb 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+abb a = r + ⌊ a b ⌋ b
所以 d|a d ′ | a
即(b,a mod b)的公约数是的(a,b)公约数
所以(b,a mod b),(a,b)公约数相同,其最大公约数也相同

code

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+(aab×b)y2=ay2+bx2ab×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=x2ab×y2 x 1 = y 2 , y 1 = x 2 − ⌊ a b ⌋ × y 2
恒等定理:两个多项式相等,则这两多项式最高次数相同,且对应次数项的系数相同.
通过递归我们可以不断的推出x1,y1,最终达到求解ax+by=gcd(a,b)的目的。

code:

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;
}

扩展欧几里得的应用

扩展欧几里得的应用主要有三个方面:

  • 解不定方程
  • 求解线性同余方程
  • 求模的逆元

1、解不定方程

求解不定方程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=y0q x = x 0 + p , y = y 0 − q ( x0,y0 x 0 , y 0 为上述过程中解出的特解x,y),且 a(x0+p)+b(y0q)=c a ( x 0 + p ) + b ( y 0 − q ) = c .
可得 ap=bq a p = b q .
又因为 a(x0+p)+b(y0q)=c a ( x 0 + p ) + b ( y 0 − q ) = c
所以p,q应为a,b的公倍数
那么我们可以得到

a(x0+tlcm(a,b)a)+b(y0tlcm(a,b)b)=c a ( x 0 + t ∗ l c m ( a , b ) a ) + b ( y 0 − t ∗ l c m ( a , b ) b ) = c

所以得到通解

x=x0+tlcm(a,b)a,y=y0tlcm(a,b)b x = x 0 + t ∗ l c m ( a , b ) a , y = y 0 − t ∗ l c m ( a , b ) 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 )


2、求解线性同余方程

求解:

axb(modm) a x ≡ b ( mod m )

mod为取余数,那么原式可变为
axmy=ax+m(y)=b a x − m y = a x + m ( − y ) = b

ax+my=b a x + m y = b

使用前文的方法解 ax+my=b a x + m y = b 即可


3、求模的逆元

ax1(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 的乘幂

你可能感兴趣的:(扩展欧几里得)