扩展欧几里得——解ax+by = c、ax≡c(mod m)

解ax+by = gcd(a, b)

扩展欧几里得算法可以用来解这样一个方程: a x + b y = g c d ( a , b ) ax+by = gcd(a, b) ,其中a,b是起初给定的数值(根据数论中的相关定理可以证明肯定有整数解 ,我也信了)

欧几里得算法中(辗转相除法),它总是把求解gcd(a,b)转化为gcd(b,a%d),当b=0时返回a,此时的a就是gcd,因为达到递归边界时,有a* 1+b* 0=gcd成立,此时也有x=1,y=0

int gcd(int a,int b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}

求: a x + b y = g c d ( a , b ) ax+by = gcd(a, b) 的一组整数解(x,y),观察:
ax+by = gcd(a, b) \Longrightarrow 两个未知数x,y

根据欧几里得算法里面a,b的变化规律,可以再写出一个辅助式子:
bx2+a%by2 = gcd(b,a%b) \Longrightarrow +两个未知数x2,y2

由欧几里得算法可知,若b \neq 0:gcd(a,b)=gcd(b,a%d)
所以:ax+by = bx2+a%by2
即:ax+by = bx2+(a-a/b)y2
即:ax+by = ay2+(b-a/b)x2
所以:x = y2,y = x2 - (a / b) y2

如果一直这样下去,递归到边界:b=0时,返回x=1,y=0,回溯的过程我们就可以求出最初的x,y的值。

ax+by = gcd通解:
在这里插入图片描述
a*b/gcd是a和b的最小公倍数

解ax+by = c

ax+by = c存在解的充要条件是c%gcd==0,ax+by = c的通解和ax+by = gcd一样,唯一不同是初始解(x,y)不同:
在这里插入图片描述
模板:

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

Question1:如果需要求该方程的最小非负整数解,该如何调整?
容易发现 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) 等价于 a ( x k b ) + b ( y + k a ) = g c d ( a , b ) a∗(x−k∗b)+b∗(y+k∗a)=gcd(a,b)

所以对于x的调整为x=(x%b+b)%b

对于y的调整为y=(y%a+a)%a

同余式ax≡c(mod m)的求解

同余式:对于整数a、b、m来说,如果m整除a-b(即(a-b)%m==0),那么就说a与b模m同余,对应同余式为a≡b(mod m),m为同余式的模。例如10与13模3同余,记为10=13(mod 3)。

此处要解决的就是同余式ax≡c(mod m)的求解。根据同余式的定义,有
(ax-c)%m=0成立,因此存在整数-y使得ax-c=-my,即得ax+my=c。

由扩展欧几里得中的结论,当c%gcd(a,m)==0,是方程才有解。

例题:https://www.luogu.org/problem/P1082
代码:

#include<bits/stdc++.h>
using namespace std;
typedef int LL;
const int N=2e6;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    LL gcd=exgcd(b,a%b,x,y);
    //a%b也可以写成a-a/b*b,最开始写成a-b*a/b可能爆精度了,wa了两次
    LL temp=x;
    x=y;
    y=temp-a/b*y;
    return gcd;
}
int main()
{
    LL a,b,x,y;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        exgcd(a,b,x,y);
        x=(x%b+b)%b;
        printf("%d\n",x);
    }
}
发布了52 篇原创文章 · 获赞 26 · 访问量 3172

猜你喜欢

转载自blog.csdn.net/qq_43803508/article/details/96432414