zoukankan      html  css  js  c++  java
  • 「欧几里得与扩展欧几里得算法」学习笔记

    $$y-=x*(a/b)$$

    $$(c/g(x_0+k*b/g),c/g(y_0-k*a/g))$$

    欧几里得算法

     (gcd(a, b)) 表示 (a,b) 的最大公约数。

    欧几里得辗转相除法:

    $gcd(0,a) = a$

    $gcd(a,b) = gcd(b, a mod b), b > 0$

    算法证明

      设 $ a = bq + r $,则需证明的是 $ gcd(a,b) = gcd(b, r) $

      可以通过证明$ (a,b) $的任何公因子必定也是$ (b,r) $的公因子,且$ (b,r) $的任何公因子必定也是$ (a,b) $的公因子

      设(d)为(a, b)的任意一个约数 $ (d > 0)$,则有(d|a, d|b)。可以设(a = sd, b = td) ((s, t) 为整数)

      ∴ (r = a - bq = sd - tdq = d(s - tq))   ∴ (d|r)

      故$ (a,b) $的所有约数都是( (b,r))的约数。

      可再次证明( (b,r) )的所有约数都是( (a,b))的约数。

      故 $ gcd(a,b) = gcd(b, r) $

    扩展欧几里得算法 EXGCD

    Exgcd用来求解方程:$ ax + by = gcd(a,b) $ (关于解的存在性证明可参见 贝祖定理 )

    很明显该方程的解不止一个。先考虑解出一组特解

    求解过程

    特殊的,当$b = 0$时,$gcd(a,b) = a$,故解得$x = 1, y = 0$

    一般的,设:$$ egin{cases} ax_1 + by_1 = gcd(a,b) \ bx_2 + (a\%b)y_2 = gcd(b,a\%b) end{cases} $$

    由欧几里得算法可得$gcd(a,b) = gcd(b, a\%b)$,因此:$$ ax_1 + by_1 = bx_2 + (a\%b)y_2 $$$$ = bx_2 + (a - left lfloor a / b ight floor*b)y_2 $$$$ = bx_2 + ay_2 - left lfloor a / b ight floor*by_2 $$$$ = ay_2 + b(x_2 - left lfloor a / b ight floor y_2) $$

    因此$$ax_1 + by_1 = ay_2 + b(x_2 - left lfloor a / b ight floor y_2)$$

    由恒等式的性质可得一组特解:$$ egin{cases} x_1 = y_2 \ y_1 = x_2 - left lfloor a / b ight floor * y_2 end{cases} $$

    因此倒推即可

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

    通解求法

    设$ k_1 = left lfloor a / gcd(a,b) ight floor , k_2 = left lfloor b / gcd(a,b)  ight floor$ 。$k_1, k_2$一定互质

    同时除以$gcd(a,b)$,得$ax / gcd(a,b) + by / gcd(a,b) = 1$,即$ k_1x + k_2y = 1 $

    要求得通解,并使等式仍然成立,(x, y)不可能同时变大或变小,不然等号不能成立。故(x, y)的大小变化相反。

    设(x)增大(d_1),(y)减小(d_2), 可得(a(x + d_1) + b(y - d_2) = gcd(a, b))

    通解即为( (x + k * d_1, y - k * d_2) ) (k为常数,且为整数)

    与前面的做法相同,两边同时除以(gcd(a,b)),可得$$a(x + d_1) / gcd(a,b) + b(y - d_2)  / gcd(a,b) = 1$$

    即$$k_1(x + d_1) + k_2(y - d_2) = 1$$

    由于$k_1x + k_2y = 1$, 两边同时减去1, 得$$k_1d_1 =  k_2d_2$$

    由于(k_1, k_2)互质,故(d_1, d_2)一定可以满足$$k_1 = d_2, k_2 = d_1$$

    因此代入可得$$a(x + k_2) + b(y - k_1) = gcd(a, b)$$

    因此通解为$$ (x + k * k_2, y - k * k_1) $$

    故解得通解为$$ (x + k * left lfloor b / gcd(a,b)  ight floor, y - k * left lfloor a / gcd(a,b)  ight floor) $$

    求解线性不定方程

    求解$ax + by = c$

    当$gcd(a,b) | c$时方程一定有解,否则无解

    在方程 $ax_0 + by_0 = gcd(a,b) $ 两边同时乘以 $c / gcd(a,b)$ 可得 $ ax_0 * c / gcd(a,b) + by_0 * c / gcd(a,b) = c $

    在(a, b)的值并没有改变的情况下,原方程的解就是:$$ egin{cases} x = x_0 * c / gcd(a,b) \ y = y_0 * c / gcd(a,b) end{cases} $$

    关于最小正整数解

    由于$x$的通解是$x + k * b / gcd(a,b)$,因此最小正整数解为$x mod (b / gcd(a,b))$。前提是保证$b / gcd(a,b) > 0$。而会出现$b / gcd(a,b) < 0$的情况只有$a,b$同负或$b$为负数,因此特判$b$的正负即可

    注意当$x<0$时模一遍仍然为负数,所以需要模两遍:$$x' = (x mod (b / gcd(a,b)) + (b / gcd(a,b)) mod  (b / gcd(a,b)$$

    求解线性同余方程

    形如(ax≡b (mod m))
    由原方程(ax≡b (mod m))很容易推得( ax - b ) 是(m)的倍数。不妨设(ax - b)是(m)的(y)倍。则有方程$ ax - b = my $

    移项即可得$ ax - my = b $ 求不定方程即可

  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9312928.html
Copyright © 2011-2022 走看看