扩展欧几里得的推导与代码实现
引言 : 裴蜀定理(定义摘自oi wiki)
定义:
设整数a,b是不全为0的整数,则存在整数x,y,使得 ax+by = gcd(a,b)
证明:
1.若a,b有一个数为0,则x取1即可成立
2.若a,b都为正整数,gcd(a,b) 为a,b的共同因子
所以 a%gcd(a,b) = b%gcd(a,b) = 0
由(m+n)%p = m%p+n%p
可以得出 (ax+by)%gcd(a,b) = ax%gcd(a,b)+by%(gcd,a,b) = 0+0 = 0 得证
回到今天的主角扩展欧几里得算法(部分借鉴知乎用户忘忧北萱草的文章)
传统欧几里得算法是用辗转相除算出a,b的最大公约数
扩展欧几里得则是可以在既算出最大公约数的同时,算出ax+by = gcd(a,b) 中的(x,y)
在欧几里得算法中,递归根据的是gcd(a,b) = (b,a%b) = (b,a-b[a/b]) 在扩欧里也会用到这个结论
设两组解(x,y) , (x1,y1) 根据裴蜀定理可得ax+by = gcd(a,b) bx1+(a-b[a/b])y1 = (b,a-b[a/b])
由于(a,b) = (b,a-b[a/b]) 则将两个式子联立求解得 a(x-y1) + b(y-(x1-y1[a/b])) = 0
我们希望这个式子对于所有解集(x,y) 都成立 于是有 x = y1 y = x1-y1[a/b]
此时求解(x,y)已经变成了求解(x1,y1),继续递归直到求解完成。递归结束条件为b=0,此时x=1,y=0
代码实现:
int exgcd(int a, int b, int& x, int& y) //返回的是gcd(a,b) x,y要传引用
{
if(a < b) return exgcd(b, a, y, x);
if(b == 0) //递归的结束条件是 b==0
{
x = 1; y = 0;
return a;
}
else
{
int x1;
int d = exgcd(b, a % b, x1, x); //exgcd(a,b,x,y) 的实质是一位置乘三位置 + 二位置*四位置 = gcd(一位置,二位置)
y = x1 - a / b * x; //根据前文第三处黑体字可知 递归函数的三位置应该是x1,四位置应该是y1
return d; //因为x=y1 所以四位置是x
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App