扩展欧几里得算法(exgcd)

概念介绍:

用于求解:AX+BY = gcd(A,B)的解

具体过程:

预先的结论:对于AX+BY = 1,如果A,B互质,该方程X,Y一定有解。

(1)证明:

两边同时%A,得到  BY%A = 1%A

我们先看Y,Y的取值共有这么几类:n*Y+0,n*Y+1,n*Y+2......n*Y+A-1

现在证明此时BY的取值也有这么几类:我们不管n*Y,我们只管0*B,1*B,2*B...(A-1)*B

假设任取两个系数分别为m,n(0<m,n<A) 我们只需证明 (m*B-n*B)!=整数倍的a  即可证明任意两个BY的取值类都不相同,(如果存在(mB-nB)%A=0,那么就相当于(m-n)B%A=0,即0B~(A-1)B中有一个是A的倍数,即 0B~(A-1)B 任意取值都不相同

等价于不存在 任意两个0B~(A-1)B组合可以成为A的倍数)

即(m-n)*B != k*A

因为A,B互质,所以(m-n)必须是A的整数倍左右式才能相等,但是-A<(m-n)<A,证明成功。

因此BY%A可以取到0~A-1的任意余数,自然也可以取到1%A

(2)同时反证法得出不互质一定无解:

若A,B不互质,那么本式子可以化简为(A/gcd(A,B))*X + (B/gcd(A,B))*Y = 1/gcd(A,B)

很显然右式是个小数,左边永远不可能得到一个小数,故此时无整数解。

②从这个结论,我们引申出:

(1)任意A,B,AX+BY = gcd(A,B)一定有解

(2)AX+BY=K*gcd(A,B)一定有解(K为不等于0的任意整数)

这就是为什么我们可以保证AX+BY=gcd(A,B)有解的原因。

③具体实现:

(1)递归原理

利用递归实现,我们可以从这两个式子来看

ax1+by1=gcd(a,b)--->当前递归所需要求的

bx2+(a%b)y2=gcd(b,a%b)--->下一层递归需要求的

我们来找两个式子中的这两组解有什么关系:

首先,右式相等。

那么,ax1+by1 = bx2+(a%b)y2

我们把a%b写成a-[a/b]*b    ([a/b]表示整除,比如5/2=2而不是2.5)

再把右式整理一下,得到:

ax1+by1 = ay2 + b*(x2-[a/b]y2)

所以:

x1 = y2

y1 = x2-[a/b]*y2

我们可以利用下层的x2,y2直接求出当前的x1,y1

(2)递归终点

我们求gcd(a,b)什么时候结束,就是a = gcd,b=0时

此时gcd*x + 0*y = gcd

求得x = 1,y的话就等于0吧,反正都一样。

④代码:(ll 表示long long型,然后这里还有些细节自己思考一下)

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

 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
扩展欧几里得算法是求解一元一次不定方程 ax + by = gcd(a,b) 的一种方法,其中 a 和 b 是整数,gcd(a,b) 是它们的最大公约数,x 和 y 是整数解。逆元是指在模运算下,一个数的乘法逆元是指与它相乘后模运算得到 1 的数。在数论中,常常需要求一个数在模意义下的逆元,即一个数 k 满足 (k * x) % m = 1,其中 m 是模数。 下面是扩展欧几里得算法求逆元的 C 语言实现: ```c #include <stdio.h> // 扩展欧几里得算法 int exgcd(int a, int b, int *x, int *y) { if (b == 0) { *x = 1; *y = 0; return a; } int gcd = exgcd(b, a % b, y, x); *y -= a / b * (*x); return gcd; } // 求逆元 int modinv(int a, int m) { int x, y; int gcd = exgcd(a, m, &x, &y); if (gcd != 1) { return -1; // a 和 m 不互质,不存在逆元 } else { return (x % m + m) % m; // 转化为正整数 } } int main() { int a = 3, m = 11; int inv = modinv(a, m); if (inv == -1) { printf("%d 在模 %d 意义下不存在逆元\n", a, m); } else { printf("%d 在模 %d 意义下的逆元是 %d\n", a, m, inv); } return 0; } ``` 这个程序中,exgcd 函数通过递归实现扩展欧几里得算法,返回 a 和 b 的最大公约数,并且求出 x 和 y 的值。在 modinv 函数中,我们调用 exgcd 函数求出 a 和 m 的最大公约数,并且判断 a 和 m 是否互质,如果不互质则不存在逆元。否则,根据扩展欧几里得算法的结果,求出 x 的值作为 a 在模 m 意义下的逆元。注意,由于 x 可能是负数,所以要将其转化为正整数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值