zoukankan      html  css  js  c++  java
  • [知识点] 6.4.2 欧几里得算法与扩欧算法

    总目录 > 6 数学 > 6.4 数论 > 6.4.2 欧几里得算法与扩欧算法

    前言

    没什么好说的啦。

    更新日志

    Update - 20200728

    重整了一下章节之间的逻辑,以及标题进行了替换。

    子目录列表

    1、欧几里得算法

    2、扩欧算法

    3、求解

    4、应用

    6.4.2 欧几里得算法与扩欧算法

    1、欧几里得算法

    欧几里得算法(Euclidean Algorithm),又称为辗转相除法,用于计算两个正整数 x, y 的最大公约数,公式为:

    gcd(x, y) = gcd(y, x mod y)

    代码:

    1 int gcd(int x, int y) {
    2     return y ? gcd(y, x % y) : x; 
    3 }

    同时,你也可以选择使用 algorithm 库中的 __gcd(x, y) 函数。

    2、扩欧算法

    扩展欧几里得算法(Extended Euclidean algorithm)是欧几里得算法的扩展版本,简称扩欧算法。已知正整数 a, b,求得最大公约数的同时可以求得 x, y(其中一个很可能为负数),使它们满足裴蜀定理

    ax + by = gcd(a, b)

    3、扩欧求解

    求解方法和欧几里得算法类似,在辗转相除的基础上增加两个数组,具体步骤见下:

    i = 5时,s[i] = -9, t[i] = 47,分别为裴蜀定理中的 x 和 y;余数r[i]为最大公约数。

    i = 6时,s[i] = 23, t[i] = -120,用于验证正确性,验证方法:t[i] * (-2) = 240, s[i] * 2 = 46,分别为 a 和 b。 

    代码 1:

    1 int exgcd(int a, int b) {
    2     if (!b) return ob;
    3     x = oox - a / b * ox, oox = ox, ox = x;
    4     y = ooy - a / b * oy, ooy = oy, oy = y;
    5     return exgcd(ob = b, a % b);
    6 }

    (最终的 x 存放在 oox 中,y 同理)

    这是根据算法的描述自己写的代码,在参考了更多 wiki 和博客的介绍后,发现 x 和 y 并不需要弄这么多变量来存,而可以先求得最大公约数后反推 x 和 y。

    代码 2:

    1 int exgcd(int a, int b, int &x, int &y) {
    2     if (!b) {
    3         x = 1, y = 0;
    4         return a;
    5     }
    6     int res = exgcd(b, a % b, x, y);
    7     ox = x, x = y, y = ox - a / b * y;
    8     return res;
    9 }

    4、扩欧应用

    ① 求线性同余方程

    线性同余方程形如  的方程。

    由于方程和 ax + by = c 是等价的,根据扩展欧几里得定理,存在整数解等价于 gcd(a, b) 整除 c(gcd(a, b) | c)。

    所以,根据上述求解方法求得 x 和 y 后,方程两边同时除以 gcd(a, b) 且乘 c,即 cx / gcd(a, b)和cy / gcd(a, b) 为方程的一组解。                

    (gcd(a, b) = 1,且 x0, y0 为其中一组解时,所有解可以表示为 x = x0 + bt, y = y0 - at,t 为任意整数)

    代码略。

    ② 求乘法逆元

    乘法逆元全称为模意义下的乘法运算的逆元(Modular Multiplicative Inverse),如果一个线性同余方程满足:

    则 x 称为 a mod b 的逆元,记作a ^ -1。

    作为线性同余方程的一种特殊情况,思路是类似的:方程和 ax + by = 1 是等价的,存在整数解等价于 gcd(a, b) 整除 1,即 gcd(a, b) = 1,即 a 和 b 互素

    代码略。

    乘法逆元同样可以用费马小定理来求,请参见:6.4.3 费马小定理

  • 相关阅读:
    条件注释判断浏览器版本<!--[if lt IE 9]>
    动态加载js、css 代码
    C趣味题目
    shell脚本
    Logiscope学习网址
    将double型小数点后面多余的零去掉
    qt和makefile学习网址
    微软推出的工作流引擎
    java例子
    js 定义hash类
  • 原文地址:https://www.cnblogs.com/jinkun113/p/12525731.html
Copyright © 2011-2022 走看看