浅谈扩展欧几里得算法(exgcd)

在讲解扩展欧几里得之前我们先回顾下辗转相除法:

\(gcd(a,b)=gcd(b,a\%b)\)当\(a\%b==0\)的时候b即为所求最大公约数

好了切入正题:

简单地来说exgcd函数求解的是\(ax+by=gcd(a,b)\)的最小正整数解。根据数论的相关知识,一定存在一组解\(x,y\)使得\(ax+by=gcd(a,b)\)。那就来谈谈具体如何来求解吧。

根据辗转相除法的内容\(gcd(a,b)=gcd(b,a\%b)\)我们可以得到:\[ax_1+by_1=gcd(a,b)=gcd(b,a\%b)=bx_2+a\%by_2······①\]

又由于\(a\%b=a- \lfloor a\div b\rfloor\times b\)

在计算机中\(a\%b= \lfloor a\div b\rfloor\times b=a/b*b%\)所以\[bx_2+a\%by_2=bx_2+(a-a/b*b)y_2\]

将等式①变形得:\[ax_1+b(y_1+a/ b*y_2)=ay_2+bx_2\]

因为等式左右两边结构相同我们可以解得:\[\begin{cases}x_1=y_2\\y_1=x_2-a/b*y_2\end{cases}\]

在扩展欧几里得算法的最后一步即\(b=0\)的时候,显然有一对整数\(x=1,y=0\)使得\[a*1+0*0=gcd(a,0)\]

那么我们就可以通过编程实现exgcd了,请仔细体验下代码的精妙之处:

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

原文地址:https://www.cnblogs.com/kcfzyhq/p/8485063.html

时间: 2024-10-12 22:48:18

浅谈扩展欧几里得算法(exgcd)的相关文章

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

欧几里得算法:最大公因数\((gcd)\) 该算法基于: \(gcd(a,b)=gcd(b,a\)%\(b)\) 证明: 令\(a\) % \(b = r\), 则 \(a = k * b + r,\) 因此\(r = a - k * b\) 设\(d\)为\(a,b\)的公约数,那么\(d|a, d|b,\) 则\(a - k * b\) 能被\(d\)整除,即\(d|r\),即\(d|(a\) % \(b)\), 因此\(d\)是\(b\) 和 \((a\) %\(b)\)的公约数, 因此\

扩展欧几里得算法的模板实现

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组ax+by=gcd(a,b),求他的一组整数解 先给出实现代码 void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1,y=0;//gcd(a,0)显然等于1*a-0*0=a return a; } int ans=exgcd(b,a%b,x,y); int tem=x; x=y; y-=tem-(a/b)*y; return ans;} 但实

欧几里得算法与扩展欧几里得算法_C++

先感谢参考文献:http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html 注:以下讨论的数均为整数 一.欧几里得算法(重点是证明,对后续知识有用) 欧几里得算法,也叫辗转相除,简称 gcd,用于计算两个整数的最大公约数 定义 gcd(a,b) 为整数 a 与 b 的最大公约数 引理:gcd(a,b)=gcd(b,a%b) 证明: 设 r=a%b , c=gcd(a,b) 则 a=xc , b=yc , 其中x , y互质

POJ - 1061 青蛙的约会 (扩展欧几里得算法)

Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这

POJ 1061 青蛙绕地球约会-数论-(解一元一次同余方程+扩展欧几里得算法)

题意:两只青蛙同向跳,起点是x,y,每次分别跳m,n米,地球周长是L,求最少跳几次相遇. 分析: 把式子写好就发现是一个一元一次同余方程.用扩展欧几里得算法来求.这题很基本得会. 代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<queue> #define INF 100000

POJ 2115 for求循环次数-数论-(同余方程+扩展欧几里得算法)

题意:给定for循环的初始值,结束值和增量,还有一个模,求最少的循环次数. 分析: 读完题后应该就知道是一个同余的概念,所以就是解一个一元一次同余方程,像上题一样用扩展欧几里得算法.这题的trick点是k最大为32,那么2^32超出了int,要用long long,所以在1<<k时要这样做:1LL<<k,不然就WA了. 代码: #include<iostream> #include<cstdio> #include<algorithm> #inc

扩展欧几里得算法详解

一:欧几里得算法(辗转相除法) 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). 证明: a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a = kb +r 因此d也是(a,b)的公约数 因此(a

扩展欧几里得算法------扩展欧几里德算法

扩展欧几里得算法及其应用 一.扩展欧几里得算法 扩展欧几里得算法:对于不完全为 0 的非负整数 a,b,若gcd(a,b)表示 a,b 的最大公约数,必然存在整数对x,y ,使得 ax+by = gcd(a,b). 算法过程: 设 a>b,当 b=0时,gcd(a,b)=a.此时满足ax+by = gcd(a,b)的一组整数解为x=1,y=0:当a*b!=0 时, 设 a*x1+b*y1=gcd(a,b):b*x2+(a mod b)*y2=gcd(b,a mod b): 根据欧几里得原理知 g

算法学习 之 欧几里得算法和扩展欧几里得算法(二)

关于扩展欧几里得算法(Extended Euclidean Algorithm),我是在做青蛙的约会这一经典题目才接触到这个算法的.后面也有关于这一题的AC代码和解题思路. 内容:已知a, b,求解一组x,y,使它们满足贝祖等式: ax+by =gcd(a, b) 扩展欧几里得算法,就和它的名字一样是对欧几里得算法的扩展.何为扩展?一是,该算法保留了欧几里得算法的本质,可以求a与b的最大公约数.二是,已知a, b求解二元一次方程ax+by =gcd(a, b)的一组解(x,y). 证明: 假设