扩展欧几里得算法 - Exgcd

前置 - 欧几里得算法

  • 欧几里得算法是一种求 gcd(a,b) 的算法,又名辗转相除法,即为:

gcd(a,b)=gcd(b,amodb)

证明:

d=gcd(a,b)c=amodb=ak×bk=ab)。

gcd(a,b)=gcd(b,amodb)cd=adbdk

adbdk

cddc

所以 db,c 的公因数。

接着:

db, d(amodb),我们还是可以像之前一样得到以下式子

amodbd=adbdk, amodbd+bdk=ad

左边式子显然为整数

ad 也为整数,即 da,所以 b,amodb 的公约数也是 a,b 的公约数。

既然两式公约数都是相同的,那么最大公约数也会相同。

所以得证。

时间复杂度:

a>2b,那么 amodb<b

a<2b,那么 amodb<b(因为最多减 1 个 b

所以,每次 a 至少缩小 12,知道 a=0 结束,所以时间复杂度为 O(log2n)

扩展欧几里得 - Exented gcd

主要用来求解线性同余方程和不定方程(这两个是等价的)

0. 特殊的不定方程

该算法用于求解形如:ax+by=gcd(a,b) 的不定方程的解。

证明: ax+by=gcd(a,b) 一定有解

由于 gcd(a,b)=gcd(b,amodb) (辗转相除)

所以有方程 bx0+(amodb)y0=gcd(a,b)

所以:ax+by=bx0+(amodb)y0

所以 x=y0,y=x0aby0

依此类推,当 a=gcd(a,b),b=0 时,一定有 x=1,而 y 有无数种解。

所以,ax+by=gcd(a,b) 一定有解。

由上过程,可写出求解一组 x,y 的代码:

void exgcd(int a, int b, int& x, int& y) {
  if (b == 0) {
    x = 1, y = 0;
    return;
  }
  exgcd(b, a % b, y, x);
  y -= a / b * x;
}

1.求通常不定方程

设一个不定方程为:
ax+by=c

该方程有解的充要条件 cgcd(a,b) 的倍数。

证明:

设方程 ax+by=gcd(a,b)

两边同时乘以 cgcd(a,b),那么方程就变为:

acgcd(a,b)x+bcgcd(a,b)y=c

由于 a,b 定义为整数,所以 cgcd(a,b) 为整数,所以 c 一定整除 gcd(a,b)

于是乎,设 ax+by=c 的一组解为 x,y,该方程的一组解即为 x0=x×c/gcd(a,b),y0=y×c/gcd(a,b)

2. 通解

对于不定方程 ax+by=c,其所有整数解均满足:

x=x0+kb/gcd(a,b)

y=y0ka/ gcd(a,b)

x0, y0ax+by=c 的一组解,可以用 Exgcd 求出。

证明:

代回原式:

a(x0+kb/gcd(a,b))+b(y0ka/ gcd(a,b))=c

展开:

ax0+akb/gcd(a,b))+by0bka/ gcd(a,b)=c

ax0+by0=c

所以成立,得证。

posted @   固态H2O  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示