扩展欧几里得
问题描述
对于三个整数 a, b , c. 求解 的( x , y )的整数解。
推导过程
首先我们要判断是否存在解,对于这个这个存在整数解的充分条件是 c 是 gcd(x,y) 的倍数。
朴素欧几里得
对于求解 gcd(x,y)
我们需要用 朴素欧几里得定理 。
gcd(a,b)=gcd(b,a%b)
.
这个比较好证明。
假设 ,有r=a mod b,不妨设 d 为 a 和 b 的一个任意一个公约数,则有a ≡ b ≡ 0 ( mod d).
由于同余的性质 ≡ r ≡ 0 (mod d)。因此 d 是 b 和 a mod b 的公约数。
然后任意一个公约数都满足,所以这个定理成立。
代码:
int gcd(int x,int y)
{
if(y==0)
return x;
else
return gcd(y,x%y);
}
这个复杂度是 O(log) 的,十分迅速。
然后判定是否有解后,我们需要在这个基础上求一组解 (x,y),由于 a,b,c 都是 gcd (a,b) 的倍数。
对于 a,b 有负数的情况,我们需要将他们其中一个负数加上另外一个数直到非负。(由于前面朴素欧几里得定理是不会影响的)两个负数,直接将整个式子反号,然后放到 c上就行了。
我们将它们都除以 gcd (a,b),不影响后面的计算。
也就是我们先求对于 ax+by=1且 (a和 b互质)求 (x,y) 的解。
接下来我们利用前面的朴素欧几里得定律推一波式子。
** **
可得 bx+(a mod b)y=bx+(a-[]b)y
不难发现此时 x 变成了 y , y 变成了 x−⌊a/b⌋ y,利用这个性质,我们可以递归的去求解 (x,y) 。
边界条件其实和前面朴素欧几里得是一样的b=0 的时候,我们有 a=1,ax+by=1 那么此时x=1,y=0 。
这样做完的话我们用 O(log) 的时间就会得到一组 (x,y) 的特殊解。
解系扩展
**注意:这里的和是 的一组特殊解 **
通解是(d是整数)
代码:
代码说明,现根据普通欧几里得算法逐步深入到最底层(b=0),在一步一步回归
//求ax+by=gcd(a,b)的特解x,y
int exgcd(int a, int b, int& x, int& y)
{
if (b == 0)
{
x = 1,
y = 0;
return a;
}
int q = exgcd(b, a % b, y, x);
y -= a / b * x;
return q;
}
要想求的解:
注意int相乘越界
只要将 的一组特解,做如下变化:
即为一组特解。
的通解:
(d是整数) ,
求解同余方程
求关于x的同余方程 ≡ c (mod b) 的最小正整数解。
上式可以转化成,
是一组特解,
最小正整数解:
x>0时,x需要减小许多b从而达到最小正整数解,即x=x%b;
x<0时,x需要加上许多b从而达到最小正整数解,即x=x%b+b
综合起来:
x = (x % b + b) % b;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话