欧几里得算法和扩欧

7.31.2018修改

欧几里得算法

概念

在数学中,辗转相除法,又称欧几里得算法(英语:Euclidean algorithm),是求最大公约数的算法.
辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数.
两个数的最大公约数通常写成GCD(a, b),或者简写成(a, b)
(引自wikipidia)

实现

用伪代码描述

//gcd(x,y)
//(x>=y>0)
while x!=0&&y!=0
    z=x
    x=x mod y
    y=z

最后非零的就是要求的最大公约数了
而在实际编程中,可以选择递归或者递推实现(我选择递归0-0)
这是递归代码(cpp)

int gcd(int x,int y) {
    if(y) {
        return gcd(y,x%y);
    }
    return x;
}
//你也可以选择这么写=v=
int gcd(int x,int y) {return y==0?x:gcd(y,x%y);}

证明\(\gcd \left( x,y\right) =\gcd \left( y,x\% y\right)\)(\(\gcd \left( x,y\right)\)已知)

1.

设\(x=ay+r\)
设\(d=\gcd\left( x,y\right)\),\(e=\gcd \left( y,r\right)\)
因为a为整数,x,y可以被d整除
所以,r可以被d整除
所以e只可能大于等于d
假设e大于d
因为有\(x=ay+r\),且a为整数,y,r可以被e整除
推出x可以被e整除
与已知矛盾
所以e==d
得证

扩展欧几里得算法

概念

扩展欧几里得算法(英语:Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式
\(ax + by = \gcd \left(a, b\right)\)。
(引自wikipidia)

实现&证明(求解和证明\(ax+by=\gcd \left( a,b\right)\))

(注意接下来的除法,均为舍去小数点后的整除)
对于 \(a\%b\) ,我们可以用\(a-\left( a/b\right) \ast c\) 去替代
那么考虑gcd中的一步 \(\gcd \left( m,n\right)\) 和下一步 \(\gcd \left( n,m\%n\right)\)
假设有\(nx+\left( n\% m\right) y= \gcd \left( m,n\right)\)
请思考上述方程与 $ mx_{1} + ny_{1} = \gcd \left( m , n \right) $ 之间的关系
...........................................
\(\because a\%b = a - \left( a / b \right) \ast b\)
\(\therefore nx+\left( n\% m\right) y=nx+my-\left( m/n\right) ny=my+n\left( x-\left( m/n\right) \ast y\right)\)
$\therefore \begin{cases} x_{1} = y\ y_{1} = x - \left( m / n \right) \ast y \end{cases} $
就这样,我们通过一组现解得到了它之前的一组解
那如果知道了最后一步的方程的解,不就可以逆推回初始方程的解了吗....
............................................
考虑求解 $ \gcd \left(a,b\right) $ 时的最后一步(即b为0时)
有$\gcd \left(a,b\right) = \gcd\left(m,0\right) = m $
考虑方程 $ mx + 0y = \gcd\left(a,b\right) $ ,它的一个可行解为 $ \begin{cases}x=1\ y=1\end{cases} $
然后我们就得到了我们需要的一组解,接下来就是逆推的过程了
好了,逆推的过程在求gcd时可以一起完成

题目不难,留给读者自行思考
(摘自算法导论)

int exGCD(int a,int b,int&x,int&y) {
    if(b==0) {
        x=1;
        y=0;
        return a;
    }
    int r=exGCD(b,a%b,x,y);
    int x1=y;
    y=x-(a/b)*y;
    x=x1;
}

之后

这里就是各种乱搞的地方啦

1.证明当 $ a_{i} $ 和 $ x_{i} $ 均为整数时, $ a_{1}x_{1} + a_{2}x_{2} + \ldots +a_{n}x_{n} $的值一定为 $ \gcd \left( a_{1},a_{2}, \ldots ,a_{n} \right)$的整数倍

假设 $ a_{1}x_{1} + a_{2}x_{2} + \ldots +a_{n}x_{n} = \varphi $ 且 $ \varphi $ 不为$ \gcd \left( a_{1},a_{2}, \ldots ,a_{n} \right)$的整数倍
对上式两边同除以 $ \gcd \left( a_{1},a_{2}, \ldots ,a_{n} \right)$ ,显然左边为一个整数
又因为右边不为一个整数,与等式矛盾
所以 $ \varphi $ 为$ \gcd \left( a_{1},a_{2}, \ldots ,a_{n} \right)$的整数倍

CF1010C

原文地址:https://www.cnblogs.com/ullio/p/9393838.html

时间: 2024-10-09 19:53:11

欧几里得算法和扩欧的相关文章

欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍

1.欧几里得算法(辗转相除法) 直接上gcd和lcm代码. 1 int gcd(int x,int y){ 2 return y==0?x:gcd(y,x%y); 3 } 1 int lcm(int x,int y){ 2 return x*y/gcd(x,y); 3 } 2.扩欧:exgcd:对于a,b,一定存在整数对(x,y)使ax+by=gcd(a,b)=d ,且a,b互质时,d=1. x,y可递归地求得. 我懒得改返回值类型了 1 long long exgcd(long long a,

『扩欧简单运用』

扩展欧几里得算法 顾名思义,扩欧就是扩展欧几里得算法,那么我们先来简单地回顾一下这个经典数论算法. 对于形如\(ax+by=c\)的不定方程,扩展欧几里得算法可以在\(O(5log_{10}\min\{a,b\})\)的时间内找到该方程的一组特解,或辅助\(gcd\)判断该方程无解. 对于扩欧的详细讲解,可见『扩展欧几里得算法 Extended Euclid』. 那么我们注意到一个问题,扩展欧几里得算法求的只是一组特解.事实上,我们可以根据如下公式得到不定方程的通解: \[ \begin{cas

Codeforces Round #305 (Div. 2)C---Mike and Frog(扩欧+乱搞)

Mike has a frog and a flower. His frog is named Xaniar and his flower is named Abol. Initially(at time 0), height of Xaniar is h1 and height of Abol is h2. Each second, Mike waters Abol and Xaniar. So, if height of Xaniar is h1 and height of Abol is

求最大公约数的两种解法(欧几里得算法和素数分解)

最大公约数的两种解法(欧几里得算法和素数分解) 方法一: 欧几里得算法,又称辗转相除法 定理(欧几里得算法):设a和b是正整数,则存在最大求最大公因子d=(a,b)的一种算法,且存在求一组整数s,t使得d = sa+tb 举个例子:求168和60的最大公约数? 168 = 2 * 60 + 48 60  = 1 * 48 +12 48  = 4 * 12 由此得最大公约数为12 关于最大公倍数 C语言程序代码:很简单就不加注释了 #include<stdio.h> #define SWAP(a

扩展欧几里德算法.....哦,扩欧

首先推荐两篇比较好的博客 http://blog.csdn.net/lincifer/article/details/49391175 (然后下面便是一个蒟蒻的总结QAQ) 扩展欧几里德算法 基本算法: 对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 ax + by = gcd(a, b) = d. 证明: 设 a > b. 1. 显然当 b = 0,gcd (a,b) = a 时, x = 1,y = 0: 2. ab != 0

关于扩展欧几里得算法和逆元

1.扩欧 a*x1+b*y1=gcd(a,b); b*x2+(a%b)*y2=gcd(b, (a%b))= gcd(a,b); a%b=a-(a/b)*b; 联立可得 x1=y2 y1=x2-(a/b)*y2; 递归的边界为b=0 此时x=1,y=0,然后回溯即可. 为什么要x=1,y=0呢? 因为此时gcd(a,b)=gcd(a,0)=a,故a*1+b*0=gcd(a,b)=a;

方程的解题解和扩欧的一些总结

题目描述 给出一个二元一次方程ax+by=c,其中x.y是未知数,求它的正整数解的数量. 输入输出格式 输入格式: 第一行一个整数T,表示有T组数据.接下来T行,每行3个整数a.b.c. 输出格式: 输出T行,每行一个数,表示方程解的数量.如果正整数解的数量比65535还多输出"ZenMeZheMeDuo". 题解 这个题一看就要先用扩展欧几里得求出一组x最小的整数解然后再计算出所有的解. 代码 1 #include<bits/stdc++.h> 2 using names

总结——数论:欧几里得算法&amp;扩展欧几里得证明

一 欧几里得辗转相除法算法 设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),又因 r = a mod b,所以 gcd(a,b)=gcd(b,a mod b). 证明:①证明充分性. 设 d 为 a,b 的公约数,记作 d|a , d|b ,即a和b都可以被d整除 又因 r=a-kb , 两边同时除以d,r/d=a/d-kb/d=m,由等式右边可知m为整数, d|r , 即 d 是 (b,a mod b)的公约数, ②证明必要性 设 d 为 b, a mod b

[模板]欧几里得算法/扩展欧几里得

最大公因数(欧几里得算法) $gcd(a,b)=gcd(b\%a,a)$(不一定需要a<b) $gcd(0,b)=b$ 1 inline int gcd(int a,int b){ 2 return a==0?b:gcd(b%a,a); 3 } 扩展欧几里得 寻找$ax+by=gcd(a,b)$的一组解x,y(一定存在整数解) $ax+by=gcd(a,b)=gcd(b\%a,a)=(b-\lfloor\frac{b}{a}\rfloor*a)x'+ay'$ 所以有一组解$x=y'-\lfloo