【learning】 扩展欧几里得算法(扩展gcd)和乘法逆元

有这样的问题:

给你两个整数数(a,b),问你整数xy分别取多少时,有ax+by=gcd(x,y),其中gcd(x,y)表示xy的最大公约数。

数据范围a,b1018

求解这个问题有一种方法,叫做扩展欧几里得算法(简称扩欧),其本质是一个递归求解的过程。

首先由一个前置的结论是gcd(x,y)=gcd(y,x%y)。此处的%c++中取模操作,下同。

 

我们不妨设a>b

a0,b=0时,则显然有x=1,y=0。此时gcd(a,b)=a

b0时,我们假设我们已经求出了bx+(b%a)y=gcd(a,b)xy(这是式1),我们现在要求的是ax+by=gcd(a,b)

我们对式子1做一些微小的变式

原式=bx+(b%a)y

=bx+(aab×b)×y

=bx+ayab×b×y

=ay+b(xaby)

不难发现,x=yy=(xaby)就是一组符合条件的解。

然后无脑递归解决即可,代码很短,复杂度显然是O(log2a)的。

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

 

下面来说下这东西能干啥

我们不难发现,我们需要求a在模b意义下的乘法逆元(前提条件,ab互质)

我们可以执行一次exgcd(a,b,x,y),然后x就是a在模b意义下的逆元。

证明显然:

ax+by=1

ax1(modb)

当模数不是质数的时候你就会知道这东西有多重要。

 

posted @   AlphaInf  阅读(322)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示