码迷,mamicode.com
首页 > 其他好文 > 详细

我所理解的扩展欧几里得

时间:2015-07-12 12:52:17      阅读:110      评论:0      收藏:0      [点我收藏+]

标签:acm   gcd   

先看欧几里得算法  即辗转相除法

gcd(a, b) = gcd(b, a % b);

简单的证明

证明: 令a % b = r  
设 d 是 a,b 的公约数 即 d|a && d|b 
又 r = a – kb  所以 r|d  即a,b的公约数都是 b,r的公约数 
设 d’ 是 b, r 的公约数 即 d’|b && d’|r
又 a = kb + r  所以d’|a  即 b,r的公约数都是 a,b的公约数
所以gcd(a,b) = gcd(b, a%b);
欧几里得算法的递归代码
int gcd(int a, int b)
{
    return (b ? gcd(b, a % b) : a);
}


然后来看扩展欧几里得算法

对于二整数a b 必存在整数 x y 使得 ax+ by = gcd(a, b)  可以通过扩展欧几里得算法求出一组满足的x y

设<span style="white-space:pre">	</span>a*x1 + b*y1 = gcd(a, b)<span style="white-space:pre">			</span>(1)
<span style="white-space:pre">	</span>b*x2 + a%b * y2 = gcd(b, a%b)<span style="white-space:pre">		</span>(2)
又 gcd(a,b) = gcd(b,a%b)
所以有 a*x1 + b*y1 = b*x2 + (a-a/b*b)*y2  此处的’/’为向下取整除
化简有 a*x1 + b*y1 = a*y2 +b* (x2 – a/b*y2)
那么有 x1 = y2,  y1 = x2 – a/b*y2;
所以我们可以通过方程(2)的一组解得到方程(1)的一组解
这样递归下去 类似辗转相除法 可以发现最后总可以递归到 方程 a*x + 0*y = gcd(a, 0) (3)
而方程(3)的一组解为 x = 1, y = 0  
那么我们在递归求gcd(a,b)的过程中 就可以一起求出方程a*x + b*y = gcd(a, b)的一组解
扩展欧几里得的递归代码

ll exGcd(ll a, ll b, ll &x, ll &y)
{
    if(!b)
    {
        x = 1, y = 0;
        return a;
    }
    ll r = exGcd(b, a % b, x, y), t = y;
    y = x - a / b * y;
    x = t;
    return r;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

我所理解的扩展欧几里得

标签:acm   gcd   

原文地址:http://blog.csdn.net/acvay/article/details/46848769

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!