欧几里得/扩展欧几里得

欧几里得算法

简介

欧几里得算法,也叫辗转相除,简称 g c d gcd gcd,用于计算两个整数的最大公约数.
定义 g c d ( a , b ) gcd(a,b) gcd(a,b) 为整数 a a a b b b 的最大公约数.

引理: g c d ( a , b ) = g c d ( b , a m o d    b ) gcd(a,b)=gcd(b,a\mod b) gcd(a,b)=gcd(b,amodb)

1.设 a a a b b b 的最大公约数为 g g g,则 a = m 1 × g a=m_1\times g a=m1×g , b = m 2 × g b=m_2\times g b=m2×g 易知 m 1 m_1 m1 m 2 m_2 m2 互质。
2.设 q = ⌊ a b ⌋ q=\lfloor\dfrac{a}{b}\rfloor q=ba , r = a m o d    b = a − p × b = ( m 1 − p × m 2 ) × g r=a\mod b=a-p\times b=(m_1-p\times m_2)\times g r=amodb=ap×b=(m1p×m2)×g,由1得 b b b r r r 的最大公约数为 g g g ,且 m 2 m_2 m2 ( m 1 − p × m 2 ) (m_1-p\times m_2) (m1p×m2) 互质。

证明 m 2 m_2 m2 ( m 1 − p × m 2 ) (m_1-p\times m_2) (m1p×m2) 互质:

假设 m 2 m_2 m2 ( m 1 − p × m 2 ) (m_1-p\times m_2) (m1p×m2) 的最大公约数为 k k k,且 k ≥ 2 k \ge 2 k2(两数不互质)。
   ⟹    m 2 = n 1 × k \implies m_2=n_1\times k m2=n1×k m 1 − p × m 2 = n 2 × k m_1-p\times m_2=n_2\times k m1p×m2=n2×k
a − p × b = r    ⟺    a = p × b + r    ⟺    a-p\times b=r\iff a=p\times b + r\iff ap×b=ra=p×b+r
a = n 2 × k × g + p × n 1 × k × g    ⟺    a = n_2\times k\times g + p\times n_1\times k\times g\iff a=n2×k×g+p×n1×k×g
a = ( n 2 + p × n 1 ) × k g a=(n_2+p\times n_1)\times kg a=(n2+p×n1)×kg,又 b = n 1 × k g b=n_1\times k g b=n1×kg
a a a b b b 的最大公约数为 k g kg kg ,跟已知矛盾,即 m 2 m_2 m2 ( m 1 − p × m 2 ) (m_1-p\times m_2) (m1p×m2) 互质.

b = 0 b=0 b=0 g c d ( a , b ) = a gcd(a, b)=a gcd(a,b)=a

int gcd(int a. int b) //a,b大小不影响
{
	return b ? gcd(b. a%b) : a;
}

扩展欧几里得算法

简介

扩展欧几里德算法,简称 e x g c d exgcd exgcd 是用来在已知a, b求解一组x,y,使它们满足贝祖等式/裴蜀定理不了解可以戳一下(σ゚∀゚)σ…:*☆):
a x + b y = g c d ( a , b ) = d ax+by = gcd(a, b) =d ax+by=gcd(a,b)=d
让我们简单的推导一下过程
a x + b y = g c d ( a , b ) = g c d ( b , a % b ) = b x ′ + ( a % b ) y ′ ax+by=gcd(a,b)=gcd(b,a\%b)=bx'+(a\%b)y' ax+by=gcd(a,b)=gcd(b,a%b)=bx+(a%b)y

然后我们就可以开始了

   ⟹    a x + b y = b x ′ + a y ′ − ( a / b ) b y ′ = a y ′ + b ( x ′ − ( a / b ) y ′ ) \implies ax+by=bx'+ay'-(a/b)by'=ay'+b(x'-(a/b)y') ax+by=bx+ay(a/b)by=ay+b(x(a/b)y)

于是得到一组解 x = y ′ , y = x ′ − ( a / b ) y ′ x=y',y=x'-(a/b)y' x=y,y=x(a/b)y
接着考虑边界条件 ( b = 0 ) (b=0) (b=0) a x = g c d ( a , 0 ) ax=gcd(a, 0) ax=gcd(a,0) 显然成立.
当然,不定方程会有很多很多解,这时,我们设最小正整数解为 x 0 , y 0 x_0, y_0 x0,y0,则通解为 x = x 0 + b g c d ( a , b ) , y = y 0 + a g c d ( a , b ) x=x_0+\dfrac{b}{gcd(a, b)}, y=y_0+\dfrac{a}{gcd(a, b)} x=x0+gcd(a,b)b,y=y0+gcd(a,b)a

至于证明,它死了,将通解带入方程式即可.

应用

hdu2669(模板题)

题目描述
给定两个数 a , b a, b a,b ,求满足 a x + b y = 1 ax+by=1 ax+by=1 x , y x,y x,y x x x 为满足条件的最小正整数.

题解
用扩展欧几里得,迭代求出最小的 x x x 即可.

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;

void exgcd(LL a, LL b, LL &x, LL &y)
{
        if (!b)
        {
                x = 1, y = 0;
                return ;
        }
        exgcd(b, a%b, y, x);
        y -= x * (a/b);
}

LL gcd(LL a, LL b)
{
        return b ? gcd(b, a%b) : a;
}

int main()
{
        LL a, b, x, y;
        while (scanf("%lld%lld", &a, &b) == 2)
        {
                if (gcd(a, b) != 1)
                {
                        puts("sorry");
                        continue;
                }
                exgcd(a, b, x, y);
                while (x < 0)
                {
                        x += b;
                        y -= a;
                }
               // x = (x % b + b) % b;
                printf("%lld %lld\n", x, y);
        }

        return 0;
}

洛谷P1082(同余方程)

题目描述
求关于 x x x 的同余方程 a x ≡ 1 ( m o d b ) a x \equiv 1 \pmod {b} ax1(modb) 的最小正整数解。

题解
a x ≡ 1 ( m o d b ) &ThickSpace; ⟹ &ThickSpace; a x + b y = 1 a x \equiv 1 \pmod {b}\implies ax+by=1 ax1(modb)ax+by=1

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;

void exgcd(LL a, LL b, LL &x, LL &y)
{
        if (!b)
        {
                x = 1, y = 0;
                return ;
        }
        exgcd(b, a%b, y, x);
        y -= x * (a/b);
}

int main()
{
        LL a, b, x, y;
        scanf("%lld%lld", &a, &b);
        exgcd(a, b, x, y);
        while (x < 0)
                x += b;
        printf("%lld\n", x);

        return 0;
}

hdu1356(解不定方程)

题目描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值