扩展欧几里得算法+推论

什么是扩展欧几里得?

扩展欧几里得算法是建立在欧几里得算法(gcd)之上。

首先,我们知道有\(a*x+b*y=gcd(a,b)\)

我们怎么求这个\(x,y\)呢?

这时候我们就得使用exgcd算法,我们来推导一下吧!

\(a*x+b*y=gcd(a,b)\)
\(a*x+b*y=gcd(b,a\% b)\)
\(a*x+b*y=b*x'+(a- \left \lfloor \frac{a}{b} \right \rfloor*b)*y'\)
\(a*x+b*y= a*y'+b*(x'-\left \lfloor \frac{a}{b} \right \rfloor*y')\)

因此,根据系数对应,我们得到了

\(x=y'\),\(y=x'-\left \lfloor \frac{a}{b} \right \rfloor*y'\)

那这个式子我们显然可以在递归里面顺带算出来嘛。

再想一想,我们gcd的递归出口为\(b=0\),即\(a*x=gcd(a,b)\),所以说我们的\(x,y\)的递归出口也为\(x=1,y=0\)

代码大概长这样qwq:

long long exgcd(long long A,long long B,long long &x,long long &y)
{
    if(B==0)
    {
        x=1,y=0;
        return A;
    }
    long long t=exgcd(B,A%B,x,y),tx=x;
    x=y;
    y=tx-(A/B)*y;
    return t;
}

酱紫,我们就求出了\(x,y\)的一组解\(x_0,y_0\)


进一步推导

如果我们要求x的最小正整数解,那不免要求x的通项公式。

首先我们的推导建立在已经求出了一组\((x_0,y_0)\)使得\(a\times x+b\times y=gcd(a,b)\)

我们要求的\(x\)的通项公式是建立在\(x_0\)之上的,我们假设\(x=x_0+p\),\(y=y_0-q\)

现在问题就变为了如何求这个\(p\)。

原式变为:
\[a(x_0+p)+b(y_0-q)=gcd(a,b)\]

展开得:
\[a*x_0+a*p+b*y_0-q*b=gcd(a,b)\]

与原式\(a*x_0+b*y_0=gcd(a,b)\)相减得
\[ap=bq\]

\[p=\frac{b*q}{a}\]

我们设\(d=gcd(a,b)\),有\(a=a'*d\),\(b=b'*d\)

将上一个式子上下同时除以\(d\)得
\[p=\frac{b'*q}{a'}\]

因为\(p\)为正整数,因此我们的\(q\)至少等于\(a'\)才能使得\(p\)的取值最小
\[p=b*\frac{a'}{a}=b*\frac{1}{d}=b*\frac{1}{gcd(a,b)}\]

解毕,我们得到了\(x\)的通项公式\(x=x_0+k*\frac{b}{gcd(a,b)}\)

.

完结撒花(*′???`)?

原文地址:https://www.cnblogs.com/GoldenPotato/p/10269979.html

时间: 2024-11-01 13:43:10

扩展欧几里得算法+推论的相关文章

扩展欧几里得算法求解不定方程【例 poj 1061】

扩展欧几里得算法是数论当中一种常用的算法,他可以用如下的姿势来表达: 设a, b为不全为0的整数,则存在整数x和y,使得 gcd(a, b) = a*x + b*y. 证明就略去. 树上还有一个拉梅定理:用欧几里得算法计算两个正整数的最大公因子时,所需要的除法次数不会超过两个整数中较小的那个十进制数的倍数的5倍. 拉梅定理的一个推论:求两个正整数a, b, a > b的最大公因子需要O(log2a)3次的位运算. 至于拉梅定理有什么用,暂时还没有研究=—=. 例1 求225和21的最大公因子s,

简单数论总结2——同余方程与扩展欧几里得算法

在上一次总结过后鸽了没多久其实是快要开学赶紧来肝上两篇 今日内容--同余方程和扩展欧几里得算法 同余 同余的定义:若存在两个整数a,b,使得(a - b) MOD P为0,则称作a与b在MOD P的情况下同余 换种通俗的说法,就是,a MOD P与b MOD P相等 记作  \( a\equiv b (mod P) \) 对于整数a,b,c和自然数m,n 同余具有以下性质: 自反性:\( a\equiv a (mod P) \) 对称性:若存在\( a\equiv b (mod P) \) ,则

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

我居然现在还记不住扩欧的板子,我太弱啦! 扩展欧几里得算法解决的是这样的问题: 给定一个不定方程组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 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置.不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的.但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的.为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面. 我们把这

[NOI2002] 荒岛野人 扩展欧几里得算法

[问题描述] 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,-,M.岛上住着N个野人,一开始依次住在山洞 C1,C2,-,CN中,以后每年,第i个野人会沿顺时针向前走Pi个洞住下来.每个野人i有一个寿命值Li,即生存的年数.下面四幅图描述了一个有6个 山洞,住有三个野人的岛上前四年的情况.三个野人初始的洞穴编号依次为1,2,3:每年要走过的洞穴数依次为3,7,2:寿命值依次为4,3,1.     奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个

扩展欧几里得算法(extgcd)

相信大家对欧几里得算法,即辗转相除法不陌生吧. 代码如下: int gcd(int a, int b){ return !b ? gcd(b, a % b) : a; } 而扩展欧几里得算法,顾名思义就是对欧几里得算法的扩展. 切入正题: 首先我们来看一个问题: 求整数x, y使得ax + by = 1, 如果gcd(a, b) != 1, 我们很容易发现原方程是无解的.则方程ax + by = 1有正整数对解(x, y)的必要条件是gcd(a, b) = 1,即a, b 互质. 此时正整数对解

欧几里得算法以及扩展欧几里得算法(过河noip2005提高组第二题)

欧几里得算法:也被称作辗转相除法 gcd(a,b)=gcd(b,a%b); 终止条件a=gcd b=0; (gcd为a,b的最大公约数) 扩展欧几里得算法: a 和 b 的最大公约数是 gcd ,一定能够找到这样的 x 和 y ,使得: a*x + b*y = gcd 成立 我们只需要找到特殊解x0,y0; 则通解为 x = x0 + (b/gcd)*t    y = y0 – (a/gcd)*t 那如何求出下一组解呢 仿照欧几里得算法a=b,b=a%b代入. a%b = a - (a/b)*b

扩展欧几里得算法学习记

话说以前我刷noip题的时候就想学这个东西了,结果却一直拖到了现在…… 到了高二才会这种东西的我实在是个蒟蒻啊! 将扩展欧几里得算法之前,先讲讲欧几里得算法是什么:gcd(a,b)=gcd(b,a%b).很显然是不?但我们还是要给出证明(设r=a%b): 设x是a,b的一个公约数,由于存在k使得a=k*b+r,又由于a|x,b|x,则有r|x,所以x是b,r的公约数 设x是b,r的一个公约数,因为存在k使得a=k*b+r,且b|x,r|x,那么a|x,所以x是a,b的公约数 综上所述,a和b的所