扩展欧几里得算法笔记

扩展欧几里得算法笔记

什么是扩展欧几里得算法

扩展欧几里得算法是一种数论算法,其功能是求解这样一类二元线性不定方程:

ax+by=c

这类方程有解的条件是gcd(a,b)|c。这个结论依赖于裴蜀定理。扩展欧几里得算法能求出其一个基本形式的一组解,即:

ax+by=gcd(a,b)

接着可以通过变形获得这个基本形式的通解,而原方程的解可以通过按比例放大的方法获得。

补充:裴蜀定理

a,b是整数,且gcd(a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立。

这个定理的一个显然推论是:

“存在x,y使得ax+by=1”与“a,b互质”互为充要条件。

因此扩展欧几里得算法可以用于求解乘法逆元。

算法思路

考虑一般的欧几里得算法(即辗转相除法),它的原理是:

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

事实上

a mod b=abab

gcd(a,b)=gcd(b,a mod b)=gcd(b,abab)

因此方程可以写作:

ax+by=gcd(b,abab)

但是这样我们依然无法在求最大公约数的同时解出x,y,所以考虑:

bx+(abab)y=gcd(b,abab

这个方程和原来的方程实际上是同一种形式,于是我们可以在递归计算最大公约数的同时求解出x,y。那么接下来的问题是,如何把x,y变成x,y?很简单:

gcd(b,abab)=gcd(a,b)

bx+(abab)y=ax+by恒成立

移项以后我们得到:

x=y,y=xyab

于是大功告成。

代码

#include <bits/stdc++.h>
int exgcd(int a, int b, int& x, int& y)
{
if (a % b == 0)
{
x = 0; y = 1;
return b;
}
int r = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - (a / b) * y;
return r;
}
int main(void)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int x, y;
int d = exgcd(a, b, x, y);
if (c % d == 0)
{
x *= c / d; y *= c / d;
printf("%d %d\n", x, y);
}
else
{
puts("No");
}
return 0;
}
posted @   kyEEcccccc  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示