zoukankan      html  css  js  c++  java
  • 扩展欧几里得算法

    下面直接使用简称exgcd就好。

    先引入紫书上的一个经典问题,求直线方程ax+by+c=0的所有整数解。

    我们先来看一个简单的,求ax+by=gcd(a,b)的一组整数解。额,看起来没啥变化。。。但实际上这样就有了固定的套路——exgcd。

    放一段代码:

    1 void exgcd(int a, int b, int &d, int &x, int &y) {
    2     if (!b) {d = a; x = 1; y = 0;}
    3     else {exgcd(b, a % b, d, y, x); y -= x * ( a / b);}
    4 }

    上述代码怎么得到的呢?其实里面还是有欧几里得算法的影子的,新问题是求解那个方程。显然当b=0时,x=1,y=0是一组解,接下来只需要找到每个解与上一解的关系就可以了。

    这里说的一个一个解是针对欧几里得算法递归分层而言的。

    设x',y'是方程bx+(a%b)y=d的一组解(同时d也是a和b的最大公约数),有d=bx+(a%b)y,a%b=a-[a/b]*b,整理可得d=ay'+b(x'-[a/b]*y')。

    这样就有x=y',y=x'-[a/b]*y'。我们一步步推就能求出ax+by=gcd(a,b)的一组解。

    那么其他解呢?假设我们已求出x,y是一组解,x',y'是另一组解,则ax+by=ax'+by',a(x-x')=b(y-y'),两边同除以gcd(a,b),得a'(x-x')=b'(y-y'),那么一定有a'|(y-y'),设y-y'=ka',可以得到x'=x-kb'。

    也就是说,对于一组特解x0,y0来说,x0+kb',y0-ka'就可以表示所有整数解。然而我们并未使用ax+by=gcd(a,b)这一条件,因此对其他形如ax+by=c的方程也成立。

    回到最初的问题,ax+by+c=0。我们可以先求出ax+by=gcd(a,b)的所有解,若gcd(a,b)|c,那么对于已求出的每组解,x*(c/gcd(a,b)),y*(c/gcd(a,b))就是该问题的所有解。

    补充一点,exgcd求出那组特解是满足|x|+|y|最小的一组解。

  • 相关阅读:
    马氏距离的深入理解
    Mahalanobis Distance(马氏距离)
    Weka EM 协方差
    数据挖掘、概率分析与决策支持
    二、 Android中gravity与layout_gravity的区别
    一、 Android完全退出应用程序
    python configparse
    时间戳与时间互转
    python argparse
    时间插件
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9717730.html
Copyright © 2011-2022 走看看