欧几里得算法证明

欧几里得算法证明:

(a,b)=(b,amodb)

S1a,b 的所有公约数的集合,S2b,amodb的所有公约数的集合

如果 ab 为正数,amodb=abab

xS1,x|a,x|b

amodbx=axbxt

t=ab为一个整数,所以x|(amodb)

xS2,x|a,x|(amodb)

amodb=abt

ax=bt+abtx=bxt+abtx

x|a

S1=S2,两个集合相等,最大值肯定相等。

如果 ab 为负数,C++中 amodb=abab

同理,(a,b)=(b,amodb)也成立。


易证,如果 b|ab 就是两者的最大公约数(公约数不可能大过 b )。

下面证明该递归一定会结束。

假设死循环,说明一直有 amodb0

0<amodbb1

递归gcd(b,a%b)

0<bmod(amodb)amodb1b2

...

0<amodb1 的时候,amodb=1,下一层递归时一定有 b|a(1能整除任何数)。

这与假设矛盾,所以一定会结束递归。


下面证明时间复杂度。

首先amodb<a2

amodb=abt

t=ab>0?ab:ab

p=ab>0

tp<t+1

假设上式不成立。

abta2

a2bt

ab2t

p2t

ab,p=ab1,t1

t+t1+t

但是p<t+12t

p2t

矛盾。

a/b<0类似。

如果a<b,gcd(b,a%b)=gcd(b,a),就变成了a>b的情况了(多递归一次)。

接下来a%b一定小于b,所以第二个参数一定是最小的。

然后b就是小的那一个,因为每次是a%b<a/2,最后就到了b=1的时候,用不到logn次就行了。


扩展欧几里得算法

exgcd(a,b,x,y)=exgcd(b,a%b,y,x)

by+x(a-kb)=d=by+xa-kxb=xa+b(y-kb)(k是C++里面向零取整的a/b)。

所以x不变,y减掉a/b*b就行了。

假设我们现在已经求出了一组解(x,y),因为ax+by=t,所以y=(t-ax)/b和x一一对应。

要找出所有的解,就要找出距离x最近的另外一个x0。

设d=x0-x,要让|d|最小。

a(x+d)+by0=t,y0=(t-ax-ad)/b=(t-ax)/b-ad/b。

也就是y0=y-ad/b

要让x0,y0都是整数,d就是整数,ad/b也是整数

设t=gcd(a,b)

a/b*d是整数

把a/b约分,a0/b0*d

这样就去除了a、b公因数的影响。

b0一定是d的约数,d一定是b0的倍数

因为要让|d|最小,取d=正负b0即可

也就是b/t,那么y就是相应减去a/t。

这样就能找出所有解了。


关于裴属定理

存在性:用扩展欧几里得算法可以构造出一组解。

S(a,b)=t|t=ax+by,x,yZ

p:xS(a,b)
q:(a,b)|x

pq

d=(a,b)d|a,d|b,d|(ax+by)=t

所以 ¬q¬p

也就是如果x不是d的倍数,它就不是S的元素,也就是说任何一个ax+by都不等于x,也就是说x无解。

line

posted @   Zlc晨鑫  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示