扩展欧几里得总结

贝祖定理 如果 \(a,b\) 是整数,那么一定存在整数 \(x,y\) 使得 \(ax+by=gcd(a,b)\)

判断有解性 如果 \(ax+by=m\) 有解,那么 \(m\) 一定是 \(gcd(a,b)\) 的若干倍。如果 \(ax+by=1\) 有解,那么 \(gcd(a,b)=1\)

辗转相除法求 \(gcd\)

int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a % b);
}

扩展欧几里得求解

对于方程 \(ax+by=gcd(a,b)\) ,我们有:

\[\begin{split} ax_1+by_1 &= gcd(a,b) \\ bx_2+(a\%b)y_2 &= gcd(b,a\%b) \end{split}\]

两式均满足贝祖定理,且一定存在解。

我们将 \((a\%b)\) 换成 \((a - \lfloor \frac{a}{b} \rfloor \cdot b)\) 有:

\[bx_2+(a - \lfloor \frac{a}{b} \rfloor \cdot b)y_2 = gcd(b,a\%b) \]

由于 \(gcd(a,b)=gcd(b,a\%b)\) ,联立两式得:

\[\begin{split} x_1 &= y_2 \\ y_1 &= x_2 - \lfloor \frac{a}{b} \rfloor\cdot y_2 \end{split}\]

易得,边界条件为:

\[gcd(a,0)=a \\ ax_0+by_0=a\ \Rightarrow\ x_0 =1;y_0=0 \]

扩展欧几里得的通解

\(x_c,y_c\) 为算法求出的一组解,那么方程的通解为:

\[\begin{split} x &= x_c + k \cdot \frac{b}{gcd(a,b)} \\ y &= y_c - k \cdot \frac{a}{gcd(a,b)} \end{split}\]

#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

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 temp = y;
    y = x - (a / b) * y;
    x = temp;
    return r;
}
int main()
{
    int a, b;
    cin >> a >> b;
    int x, y;
    int d = exgcd(a, b, x, y);
    cout << x << " " << y << " " << d << endl;
    return 0;
}

posted on 2019-08-29 23:53  solvit  阅读(135)  评论(0)    收藏  举报

导航