首页 > 编程语言 >算法学习笔记-exgcd

算法学习笔记-exgcd

时间:2023-08-08 22:47:11浏览次数:38  
标签:方程 gcd 笔记 算法 exgcd 有解 operatorname mod

前言:

\(\operatorname {exgcd}\),顾名思义,是 \(\gcd\) 的一种扩展。\(\gcd\) 是求最大公因数,所用到的是辗转相除法,基于 \(\gcd(a,b)=\gcd(b,a\mod b) (a>b)\) 的原理,在学习 \(\operatorname{exgcd}\) 前,请确保已掌握 \(\gcd\) ,并懂得一点数学归纳法。如果您已掌握这些前置知识,请开始学习。

例题:

先看这样一道题,给定整数 \(a,b\) ,求 \(x,y\) 使得 \(ax+by=1\)。

性质:

性质1:

这显然是一道数学题(废话),考虑将原式根据乘法分配律转换为 \(\gcd(a,b)\times (\frac{a}{\gcd(a,b)}x+\frac{b}{\gcd(a,b)}y)=1\)。而如果两个整数乘积为 \(1\),则他们一定为 \(1\),因此 \(\gcd(a,b)=1\) ,换句话说,\(a,b\) 互质。

综上所述,我们得出性质,若原方程有解,当且仅当 \(a,b\) 互质。

性质2:

这个性质就比较简单,它实际上是类似于递归边界的东西,并不需要怎么推导。考虑当 \(a=1,b=0\) ,原方程有一组解为 \(x=1,y=0\)。

推导:

先看原式:\(ax+by=1\)。
设 \(m = a\mod b\),\(k=\frac{a}{b}\),则 \(a=bk+m\)。(其实就是余数和商)。
设有一个和原式一样的方程 \(x'm+y'b=1\);

根据 \(m\) 的定义,转换为 \(x'(a-kb)+y'b=1\);

将式子打开,变为 \(x'a-x'kb+y'b=1\);

合并同类项,变为 \(x'a-(y'-kx')b=1\);

可以发现一个神奇的事情,转化后的方程与原方程本质是一样的!唯一变化的只有 \(x\) 与 \(y\) 的值。也就是说,若 \(x'(a \mod b)+y'b=1\) 有解,那么 \(ax+by=1\) 也一定有解。而且这个解就是 \(x=x'\), \(y=y'-kx'\)(将所推方程带入)。而根据 \(\gcd\) 的写法,两个互质的数到递归边界时一定是 \(a=1,b=0\)。因为 \(a=1,b=0\) 的情况是有解的,所以 \(\gcd(a,b)=1\) 也是有解的,这也进一步证明了上面的性质。

如果你到这里都听懂了,那么下面的问题就很简单了,只需将 \(x,y\) 代入下面推出来的式子即可。

结论:

通过以上推导,可以得出:

  1. 原方程有解当且仅当 \(gcd(a,b)==1\)。
  2. 原方程解为 \(y = \begin{cases} x=1,y=0 & a=1,b=0 \\ x=x',y=y'-kx (x'a \mod b +y'b = 1, k = \frac{a}{b}) & otherwise \\ \end{cases} \)

实现:

\(\operatorname{exgcd}\) 模版见下(递归):

点击查看代码
void exgcd(int a, int b, int &x, int &y)
{
	if(a == 1 && b == 0)//边界 
	{
		x = 1, y = 0;
		return ;
	}
	exgcd(b, a % b, y, x);
	//这里之所以要交换x和y的位置,是因为b与a%b交换了,根据公式要把x,y也换过去 
	y = a / b * x;//按照公式赋值,由于是引用,所以x的值已经更改了。 
}

总结:

第一次学 \(\operatorname{exgcd}\) 时,刚开始看到结论十分蒙,等到搞清楚证明时觉得这个证明妙不可言。笔者认为,学习 \(\operatorname{exgcd}\) 应不仅只会背代码,更要明白证明的过程,最好自己手推一遍。因为证明不仅是解决之后的许多与 \(\operatorname{exgcd}\) 的题有关,更能扩展思维,对数轮有很大帮助。

鉴于笔者也是蒟蒻,文中给出的部分推导过程与表述可能不严谨,欢迎大佬在评论区指出。

标签:方程,gcd,笔记,算法,exgcd,有解,operatorname,mod
From: https://www.cnblogs.com/zhangxiao666qwq/p/suanfa-exgcd.html

相关文章

  • 《CUDA编程:基础与实践》读书笔记(1):CUDA编程基础
    1.GPU简介GPU与CPU的主要区别在于:CPU拥有少数几个快速的计算核心,而GPU拥有成百上千个不那么快速的计算核心。CPU中有更多的晶体管用于数据缓存和流程控制,而GPU中有更多的晶体管用于算数逻辑单元。所以,GPU依靠众多的计算核心来获得相对较高的并行计算性能。一块单独的GPU无......
  • C++ Primer Plus 第6版 读书笔记(8)第 8章 函数探幽
    第8章函数探幽本章内容包括:内联函数。引用变量。如何按引用传递函数参数。默认参数。函数重载。函数模板。函数模板具体化。通过第7章,您了解到很多有关C++函数的知识,但需要学习的知识还很多。C++还提供许多新的函数特性,使之有别于C语言。新特性包括内联函数、......
  • [学习笔记] 凸包
    凸包由于\(Andrew\)算法较快,所以主要介绍\(Andrew\)的实现方式我们把输入按照\(x\)为第一关键字,\(y\)为第二关键字进行从小到大排序,保证了\(1\)和\(n\)两个端点把凸包分成了两个部分(称为凸壳),从\(1\)遍历到\(n\)再从\(n\)遍历到\(1\),把遍历到的点压入栈,使......
  • PMP 学习笔记(八)
    07.25星期二缓冲只用于预测性项目,应对风险来用精益方法不留一丝丝的多余Moscow是排序工具成本效益分析是判断值不值得的工具投资汇报分析是判断值不值得的工具挣值分析是判断成本、进度、成本的工具项目经理应密切关注影响项目的内外部事业环境因素的变化替代也属于风险......
  • 渗透测试学习笔记
    渗透测试:渗透测试基本流程:确定目标:信息收集:是指通过各种方式获取所需要的信息,便于在后续渗透过程更好进行,例如目标站点IP、中间件、脚本语言、端口、邮箱······漏洞探测(手动/自动):漏洞分析:漏洞利用(手动/自动):信息整理:形成报告:......
  • 06-页面置换算法
    06-页面置换算法一、功能与目标功能:当缺页中断发生,需要调入新的页面而内存已满时,选择内存当中哪个物理页面被置换目标:尽可能地减少页面的换进换出次数(即缺页中断的次数)。具体来书,把未来不再使用的活短期内较少使用的页面换出,荣昌只能在局部性原理指导下依据过去的统计数据来......
  • 《Java编程思想第四版》学习笔记07
    到底应该使用一个接口还是一个抽象类呢?若使用接口,我们可以同时获得抽象类以及接口的好处。所以假如想创建的基础类没有任何方法定义或者成员变量,那么无论如何都愿意使用接口,而不要选择抽象类。事实上,如果事先知道某种东西会成为基础类,那么第一个选择就是把它变成一个接口。只有在必......
  • openGauss学习笔记-34 openGauss 高级数据管理-SCHEMA
    openGauss学习笔记-34openGauss高级数据管理-SCHEMASCHEMA又称作模式。通过管理SCHEMA,允许多个用户使用同一数据库而不相互干扰,可以将数据库对象组织成易于管理的逻辑组,同时便于将第三方应用添加到相应的SCHEMA下而不引起冲突。每个数据库包含一个或多个SCHEMA。数据库中的每个......
  • tesserocr笔记
    tesserocr安装教程pipinstalltesserocr出错:tesserocrWHL下载whl安装方式:pipinstall文件名.whl报错“RuntimeError:FailedtoinitAPI,possiblyaninvalidtessdatapath:”修改路径为纯英文修改tesserocr环境变量......
  • 0807笔记
    1、精讲软硬链接硬链接软链接2、压缩和解压缩tar指定目录解压缩[root@c1day02]#tarzxvf/mnt/day02/day02.tar.gz-C/mnt/day02/yu/study1.txtstudy2.txtstudy3.txtstudy4.txtstudy5.txtstudy6.txtwork11/work22/work33/work44/work55/zip[root@c1day02]#......