gcd and exgcd
来源:互联网 发布:少儿编程培训内容 编辑:程序博客网 时间:2024/06/10 08:15
- 数论入门基础
- 最大公约数
- 问题1
- 解法1
- 解法2
- 求最大公约数的欧几里德算法
- 扩展欧几里得
- 问题
- 解法
- 最大公约数
数论入门基础
最大公约数
问题1
给定平面上的两个格点
P1=(x1,y1) 求线段P1P2上有几个格点P2=(x2,y2)
−109<=x1,x2,y1,y2<=109
解法1
枚举所有的合法的
判断
数据范围大,我们需要更快的算法
解法2
假设我们从(x1,y1)出发已经找到了离它最近的一个格点P0,那么从P0出发走相同长度肯定也是一个整数格点,就这样一路找下去,最终恰好能找到(x2, y2),中间的每一段都是等长的,你可以假设最终到的点不是(x2,y2),而是延伸出去的某个点,那么显然P0就不是离(x1, y1)最近的一个格点了。
所以我们证明了一个性质
线段上的所有的整数格点恰好都在这条线段的K等分点上
要满足等分点都是整数,所以K必须为X距离和Y距离的公约数,我们需要求最大的K,所以就是两个距离的最大公约数了
求最大公约数的欧几里德算法
- 更相减损术
- 辗转相除法
这两种方法是一样的,下面是上面的优化
int gcd(int a, int b) { while(a != b) { if (a > b) { a -= b; } else { b -= a; } } return a;}int gcd(int a, int b) { if(b == 0) return a; return gcd(b, a % b);}
为什么这样子做是对的呢?
假设 g 为a b的某个公约数,那么对于任意一个g都有如下两个式子
a b更相减损,变的只是前面的k,无论怎么减g还是他们的约数,一直到最后两个数变成相同的,g还是他们的约数
在更相减损的过程当中,所有的公约数信息都没有丢,也不会增加,跟原来一样,但是数据变小了哦,那么一直变小会发生什么呢?
对于任意一个公约数g都满足最后变成的两个相等的数为g的倍数。所以辗转相减之后的数也是最大公约数
既然所有的公约数信息都没丢,这两个数的公约数也是原来a b的公约数,那么
其实上面的辗转相减法,每次就是最大公约数的两个系数k1, k2在辗转相减,最终变成1(他们的最大公约数是1),这个辗转相减的过程可以描述为
所以这个方程其实一定有解,因为刚才已经证明k1 k2辗转相减一定能得到他们的最大公约数1。
扩展欧几里得
问题
一个游戏
有向前向后无线延续的格子, 每个格子都写有整数。其中0号格子是起点, 1号格子是终点。 而骰子上只有a,b,-a,-b四个整数,所以根据a和b的值得不同,有可能无法到达终点。掷出四个整数各多少次可以到达终点?
解法
上述问题归结起来就是
如果
实际上一定存在整数对(x, y)使得
假设已经求得了
1:
b∗x′+(a%b)y′=gcd(a,b)
的整数解
将
代入可得
化简一下
2:
a∗y′+b∗(x′−(a/b)∗y′)=gcd(a,b)
所以,解出了1式,就可以由2式得到原方程的解
特殊的,当b = 0时,
下面的代码解决
int extgcd(int a, int b, int &x, int &y) { int d = a; if(b != 0) { d = extgcd(b, a % b, x, y); x -= (a / b) * y; std::swap(x, y); } else { x = 1; y = 0; // g x+ 0 * y = g, y can be any number } return d;}
递归算到最后y其实可以取任意整数。但是取的太大容易导致使得最后算出来的解爆int之类的事情
下面我们来看一下最终算出来的解
由x y的计算方法x -= (a / b) * y可以知道,x y始终是在max(|a|, |b|)的绝对值范围内的,因此a*x + b*y = gcd(a, b)最后算出的x y的绝对值大小跟a b是同一个级别的。
扩展欧几里德其实就是欧几里德,欧几里德其实就是辗转相减,全是一样的!
通解:
- gcd and exgcd
- gcd and exgcd
- gcd&exgcd
- {模板}Gcd及ExGcd
- gcd与exgcd
- 【模板】【数论】gcd和exgcd
- ACM_欧几里得(GCD) 扩展欧几里得(EXGCD)
- 欧几里得gcd+扩展欧几里得exgcd模板
- 暑假集训之gcd&exgcd简介
- exgcd
- Exgcd
- exgcd
- exgcd
- EXGCD
- GCD ExGCD 扩展欧几里德算法证明与算法
- 数论专题小结:gcd算法与exgcd算法
- gcd&exgcd O(∩_∩)O哈!
- GCD exGCD 逆元 快速幂 大数取模
- ROC和AUC
- 洛谷P1576 最小花费
- Java+Selenium3方法篇34-如何处理日历控件
- 十九、命令模式——设计模式学习笔记
- 线性回归和逻辑回归
- gcd and exgcd
- jQuery下的ajax 三级联动
- arrayadapter simpleadapter baseadapter
- PAT乙级 1056. 组合数的和(15)
- Genymotion连接电脑本地服务器方法
- LINQ系列:Linq to Object联接操作符
- 《机器学习》学习笔记三 决策树
- 2017.07月学习计划
- 两数组的交