欧几里得gcd/extend_gcd

正式叙述前还写了一点自己的小感受。

问题:求两个正整数a,b的最大公约数

大神看来是很简单的问题,但是对于去年夏天刚学python的我来说,这是个很难的问题,还记得当时一晚上睡不着都在想怎么快一点的求出最大公约数,后来猜测最小公倍数的求法,还有最后想出来的欣喜若狂,我现在还记忆犹新。

 

还记得看过一个小梗:一个农民种着种着地,一排一排的种,突然陷入深思,沉思良久,回去算了很久以后,借了钱疯了似的坐火车跑到中科院门口,等来数学系教授,向他讲述了自己的重大发现。大概意思就是,自己从田地中大彻大悟,发明了一种快速计算方法,不用计数,不用加法,不用数学,还给了教授一张伟大的定律表。

教授告诉他:你真的很厉害,你的发现很伟大,能在种田中悟出来这种算法可不容易。

 

 

 

 

 

 

 

但是,你发明的这种算法叫乘法,你给我的表,完善一下以后,叫九九乘法表。

农民继续回去种田

(这个故事告诉我们要多虚心接受知识,不要老自己想。。。。)

 

我知道了欧几里得算法以后,感觉自己就跟这个农民一样。。。。。。。

不过,知道了自己的想法就是欧几里得算法时,还是挺高兴的。。。

就当锻炼思维了吧。。只能这么安慰自己。

 

好,开始正题。。。。::

 

我当时的思路是这样的:求a,b的最大公约数,假设最大公约数是x的话,a一定可以用i*x来表示,b也一定可以用j*x来表示,我们怎么把i和j去掉,把x榨出来呢??

让这俩数不断互相相减就可以啦!

后来自己想到了互相取余。

 

我们来看正规的欧几里得算法:

首先放简介:欧几里德算法又称辗转相除法,是指用于计算两个正整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。

看代码实现:

Python

def gcd(a, b):while a != 0:a, b = b % a, areturn b

 

后来知道了欧几里得还有拓展:

可以用来求二元一次方程的通解,还可以用来求乘法逆元。 

已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式ax+by=gcd(a,b)

如果a是负数,可以把问题转化成|a|(-x)+by=gcd(|a|,b) ,然后令x'=(-x)。

//返回 d=gcd(a,b); 和对应于等式 ax+by=d 中的 x,y
long long extend_gcd(long long a,long long b,long long &x,long long &y)
{if(a==0&&b==0) return −1;//无最大公约数if(b==0){x=1;y=0;return a;}long long d=extend_gcd(b,a%b,y,x);y−=a/b*x;return d;
} 

求逆元,真的不想叙述了,上个代码算了

 //********* 求逆元 *******************
//ax = 1(mod n)
long long mod_reverse(long long a,long long n)
{long long x,y;long long d=extend_gcd(a,n,x,y);if(d==1) return (x%n+n)%n;else return −1;
} 

逆元,利用欧拉:

mod 为素数, 而且 a 和 m 互质 

long long inv(long long a,long long mod)//为素数mod
{return pow_m(a,mod−2,mod);
}

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445651.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python基础技巧总结(一)

最近总结一下python基础知识,就暂时弃坑了。 本文总结只属于python的一些骚操作。。。 后面文章自行去博客学习交流 原地交换 Python 提供了一个直观的在一行代码中赋值与交换(变量值)的方法 x, y 10, 20 print(x, y)x, y y, x print(x…

python基础技巧总结(二)

一总结的链接: 好,我们继续 一次性初始化多个变量 可以直接赋值: a,b,c,d1,2,3,4 可以利用列表: List [1,2,3] x,y,zList print(x, y, z) #-> 1 2 3 (元素个数应与列表长度相同) 打印模块路径 im…

python基础技巧总结(三)

前两篇文章: https://blog.csdn.net/hebtu666/article/details/81698235 https://blog.csdn.net/hebtu666/article/details/81698329 我们继续总结: 开启文件分享 Python 允许运行一个 HTTP 服务器来从根路径共享文件,下面是开启服务器的…

python基础技巧总结(四)

前三期请到我博客里找 https://blog.csdn.net/hebtu666 我们继续总结 except的用法和作用 try/except: 捕捉由PYTHON自身或写程序过程中引发的异常并恢复 except: 捕捉所有其他异常 except name: 只捕捉特定的异常 except name, value: 捕捉异常及格外的数据(实例) exce…

python基础技巧总结(五)

前四期到博客找:https://blog.csdn.net/hebtu666 我们继续说一些好用的函数 split Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串。 语法: str.split(str"", num…

堆的简单实现

关于堆不做过多介绍 堆就是儿子的值一定不小于父亲的值并且树的节点都是按照从上到下,从左到右紧凑排列的树。 (本文为二叉堆) 具体实现并不需要指针二叉树,用数组储存并且利用公式找到父子即可。 父:(i-1)/2 子:…

二叉搜索树实现

本文给出二叉搜索树介绍和实现 首先说它的性质:所有的节点都满足,左子树上所有的节点都比自己小,右边的都比自己大。 那这个结构有什么有用呢? 首先可以快速二分查找。还可以中序遍历得到升序序列,等等。。。 基本操…

python基础小白题

题目1:有1、2、3、4四个数,能组成多少个互不相同且无重复的三位数?都是多少? list_num[1,2,3,4] all_num[] for i in list_num: for j in list_num: for k in list_num : if (i!j) and (i!k) and (j!k): numi*100j*10k all_num…

python基础小白题2

题目11:判断101-200之间有多少个素数,并输出所有素数。 num[] for i in range(100,201): ji//2 for k in range(2,j): if i%k0: break else: num.append(i) print(一共有%d个素数\n这些素数是: %len(num),num ) 输出结果&am…

python基础小白题3

题目021:猴子吃桃问题 猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。 以后每天早上都吃了前一天剩下的一半零一个。 到第10天早上想再吃时&#x…

python基础小白题4

题目031:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。 def tm031(): 【个人备注】:按照题意要求实现了就行 week [monday,tuesday,wednesday,thursday,friday,saturday,sunday] inp…

python基础小白题5

题目045:统计 1 到 100 之和。 def tm045(): 【个人备注】:简单,但官网有人写的更简单 s 0 for i in range(1,101): si print(s) # 更简洁的方法 print(sum(range(1,101))) 题目046:求输入数字的平方,如果平方运算…

快排-荷兰国旗

在使用partition-exchange排序算法时,如快速排序算法,我们会遇到一些问题,比如重复元素太多,降低了效率,在每次递归中,左边部分是空的(没有元素比关键元素小),而右边部分只能一个一个递减移动。…

快排-前m大元素

描述 给定一个数组包含n个元素&#xff0c;统计前m大的数并且把这m个数从大到小输 出。 输入 第一行包含一个整数n&#xff0c;表示数组的大小。n < 100000。 第二行包含n个整数&#xff0c;表示数组的元素&#xff0c;整数之间以一个空格分开 。每个整数的绝对值不超过…

归并-求逆序数

考虑1,2,…,n (n < 100000)的排列i1&#xff0c;i2&#xff0c;…&#xff0c;in&#xff0c;如果其中存在j,k&#xff0c;满足 j < k 且 ij > ik&#xff0c; 那么就称(ij,ik)是这个排列的一个逆序。 一个排列含有逆序的个数称为这个排列的逆序数。例如排列 26345…

动态规划概述

注&#xff1a;第一次看不需要全理解&#xff0c;以后动态规划做多了&#xff0c;再回来看看&#xff0c;会有更深的理解 先符上其它文章&#xff0c;看完这篇就可以开始看这些咯。 萌新&#xff1a; …

动态规划-背包是否装满

很简单但是需要特别注意的&#xff0c;一定不要错。 背包&#xff1a; 有n 种不同的物品&#xff0c;每个物品有两个属性&#xff0c;v体积&#xff0c;c价值&#xff0c;现在给一个体积为 m 的背包&#xff0c;问最多可带走多少价值的物品。 状态转移方程 dp[i][j]max…

dp打开思路3:HDU1069 POJ3616 POJ1088

HDU 1069 题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1069 题意&#xff1a;把给定的长方体&#xff08;不限&#xff09;叠加在一起&#xff0c;叠加的条件是&#xff0c;上面一个长方体的长和宽都比下面长方体的长 和宽短&#xff1b;求这些长方体能…

输入输出外挂

板子不解释 //适用于正负整数 template <class T> inline bool scan_d(T &ret) {char c; int sgn;if(cgetchar(),cEOF) return 0; //EOFwhile(c!−&&(c<0||c>9)) cgetchar();sgn(c−)?−1:1;ret(c−)?0:(c−0);while(cgetchar(),c>0&&c&…

dp打开思路4:POJ1189 UVA12511 HDU2845 HBCPC K

POJ1189 http://poj.org/problem?id1189 怎么说呢&#xff0c;不算难&#xff0c;但是容易出问题 我一开始的思路是&#xff0c;第一个钉子只有一种情况&#xff0c;然后下面每个钉子&#xff1a;左边有钉子就加左边的情况数&#xff0c;右边有钉子就加右边的情况数&#x…