扩展欧几里得算法

扩展欧几里得算法

问题描述

给定 n n n对正整数 a i , b i a_i,b_i ai,bi,对于每一对数,求出一组 x i , y i x_i,y_i xi,yi,使其满足
a i x i + b i y i = g c d ( a , b ) a_ix_i+b_iy_i=gcd(a,b) aixi+biyi=gcd(a,b)

0.裴蜀定理

对于整数 a , b a,b a,b d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b)则对于任何的整数 x , y x,y x,y则一定有 d ∣ a x + b y d|ax+by dax+by,即 a x + b y ax+by ax+by一定是 g c d ( a , b ) gcd(a,b) gcd(a,b)的倍数,特别的,一定存在整数 x , y x,y x,y使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)成立。
如果 a x + b y = t ax+by=t ax+by=t,而 t t t不能被 d d d整除,则该方程无整数解。

1.扩展欧几里得

用于求解方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的解

b ≠ 0 b\neq0 b=0时,因为 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)则有

b x ′ + ( a % b ) y ′ = g c d ( b , a % b ) (1) \\bx'+(a\%b)y'=gcd(b,a\%b)\tag{1} bx+(a%b)y=gcd(b,a%b)(1)
易得 a % b = a − ⌊ a / b ⌋ ∗ b a\%b=a-\lfloor a/b \rfloor*b a%b=aa/bb,将其带入 ( 1 ) (1) (1)式中可得
b x ′ + ( a − ⌊ a b ⌋ ∗ b ) y ′ = g c d ( b , a % b ) b ( x ′ − ⌊ a b ⌋ ) + a y ′ = g c d ( b , a % b ) bx'+(a-\lfloor \frac{a}{b} \rfloor*b)y'=gcd(b,a\%b) \\b(x'-\lfloor \frac{a}{b} \rfloor)+ay'=gcd(b,a\%b) bx+(abab)y=gcd(b,a%b)b(xba)+ay=gcd(b,a%b)
由此可得

{ x = y ′ y = x ′ − ⌊ a b ⌋ ∗ y ′ (2) \left\{ \begin{array}{c}\tag{2} x=y' \\ y=x'-\lfloor \frac{a}{b} \rfloor *y'\\ \end{array} \right. {x=yy=xbay(2)
观察原有的欧几里得算法

int gcd(int a,int b)
{
    if(!b){
        return a;
    }
    return gcd(b,a%b);
}

我们所要求的 x , y x,y x,y在每一步的辗转相除中都会改变,但在最后一步,递归的出口一定是 x = 1 , y = 0 x=1,y=0 x=1,y=0。因为在辗转相除法的最后一步, b b b一定等于 0 0 0且返回值 a a a即为所求的最大公约数,即
a ∗ x + 0 ∗ y = g c d ( a , 0 ) = a a*x+0*y=gcd(a,0)=a ax+0y=gcd(a,0)=a
因此必有特解 x = 1 , y = 0 x=1,y=0 x=1,y=0 这里注意一下 x x x是只能取 1 1 1,但是 y y y可以取任何值,为了计算方便我们将其取做 0 0 0
由刚刚推导的 ( 2 ) (2) (2)我们可以知道,每一步的 x x x y y y都与下一步的 x ′ , y ′ x',y' x,y以上述公式的方式相联系,因此我们可以修改一下 g c d gcd gcd函数便可以得到一段很漂亮简洁的代码。

int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    int d,x1,y1; //我们需要用到从上一层递归栈中传过来的d,x1,y1因此这里的x和y都要传地址
    d=exgcd(b,a%b,x1,y1);
    x = y1;
    y = x1 - (a/b)*y1; 
    return d;
}
2.对于求解更一般的方程 a x + b y = c ax+by=c ax+by=c

d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b),该式成立当且仅当 d ∣ c d | c dc
求解方法如下:
首先用扩展欧几里得算法求出 a x + b y = d ax+by=d ax+by=d的特解
设特解为 x = x 0 , y = y 0 x=x_0,y=y_0 x=x0,y=y0 ,即 a x 0 + b y 0 = d ax_0+by_0=d ax0+by0=d
于是 a x + b y = c ax+by=c ax+by=c的特解为
a x 0 ( c / d ) + b y 0 ( c / d ) = c ax_0(c/d)+by_0(c/d) = c ax0(c/d)+by0(c/d)=c
通解=特解+齐次解
a x + b y = 0 ax+by=0 ax+by=0的解为 x = b / d , y = − a / d x=b/d,y=-a/d x=b/d,y=a/d
因此一般形式的解为
x = x 0 ( c / d ) + k ∗ ( b / d ) y = y 0 ( c / d ) − k ∗ ( a / d ) x=x_0(c/d)+k*(b/d) \\y=y_0(c/d)-k*(a/d) x=x0(c/d)+k(b/d)y=y0(c/d)k(a/d)
这里注意一下为什么齐次解是 x = b / d , y = − a / d x=b/d,y=-a/d x=b/d,y=a/d而不是 x = b , y = − a x=b,y=-a x=b,y=a,因为显然前者在乘上 k k k后可以取到更多的值。

3.求解一次同余方程 a x ≡ b ( m o d   m ) ax\equiv b(mod\ m) axb(mod m)

等价于求 a x = m ∗ ( − y ) + b ax=m*(-y)+b ax=m(y)+b a x + m y = b ax+my=b ax+my=b
有解的条件为 g c d ( a , m ) ∣ b gcd(a,m)|b gcd(a,m)b
特别的,当 b = 1 b=1 b=1 a , m a,m a,m互质时所求的 x x x即为 a a a的逆元
因为 a x + m y = g c d ( a , m ) ax+my=gcd(a,m) ax+my=gcd(a,m) b = 1 b=1 b=1 g c d ( a , m ) = 1 gcd(a,m)=1 gcd(a,m)=1 a , m a,m a,m 互质。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值