初级数论1:(扩展)欧几里得算法
初级数论第一节:欧几里得算法,扩展欧几里得算法,例题。
欧几里得算法
先来讲一下欧几里得算法
欧几里得算法是可以在
代码如下:
int gcd (int a, int b) { if (b == 0) return a; return gcd (b, a % b); }
证明一下这个算法的正确性。
现在需要证明
因为
证明
设
设
那么
所以
时间复杂度证明
设
如果
如果
每一轮都减半,
拓展知识:
证明:
假设斐波那契数列的相邻两项为
而相减就会变成斐波那契数列的上一项,
所以用欧几里得算法求斐波那契数列的第
时间复杂度就是
其中,
证明过程太长,此处省略
例题:
扩展欧几里得算法
扩展欧几里得算法是可以在
简称扩欧,别名
其中,
扩展欧几里得算法是用小的解算出大的解然后回退。
终止答案
欧几里得算法的终结条件是
所以我们从
即
但是取太大最后会爆
回退
先来看一下欧几里得算法,
我们只要知道了
扩展欧几里得算法也是这样,要想求
可以先求
我们先假设已经求得了
因为最后
解的变形
首先可以发现
我们现在就知道了
其次,
代入进去变成
拆开变成
然后把和
得到
然后我们发现这个方程不就是
然后就可以回退到上一层求解了。
时间复杂度证明
不难发现,
并且
代码:
void exgcd (int a, int b) { if (b == 0)//b=0 的情况答案可以直接得到 { x = 1; y = 0; return; } exgcd (b, a%b)//否则先算 exgcd(b, a % b) 的解。 int t = x;//现在的 x, y 是 bx + (a % b)y = gcd(a, b) 的解。 x = y;//刚刚证明了 ax + by = gcd(a, b) 的解 x 就是上一个方程的解 y y = t - a / b * y;//x 已被更改,所以用临时变量 t 存储上一个方程的解 x }
拓展:一般形式
题目里很少有要求
这时该怎么办呢?
如果
否则,可以证明,该方程无整数解。
例题:
两个闹钟
题意已经很明显了,就是一个扩欧。
设两个整数
整理得
另
其中,
解出来之后,
但是这个解有可能是负的,所以得尝试把他变成正的。
可以发现两个闹钟第一次同时响如果在
那么就一直加
但是会超时,用一个除法就可以了。
无尽的循环
这一道题是需要变形一下的,大家可以自己先尝试一下。
另外,注意开个
简化题意
给定
然后把同余去了,变成
把
其中,
令
最后
下节预告:中国剩余定理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)