快速指数取模运算与用扩展欧几里得算法求解最大公约数和求乘法逆元
欧几里德算法

欧几里得算法的概述欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。
其计算原理依赖于下面的定理:定理:gcd(a,b) = gcd(b,a mod 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,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证欧几里得算法原理Lemma 1.3.1 若a, b 且 a = bh + r, 其中h, r , 则gcd(a, b) = gcd(b, r).证明. 假设d1 = gcd(a, b) 且d2 = gcd(b, r). 我们证明d1| d2 且d2| d1, 因而可利用Proposition 1.1.3(2) 以及d1, d2 皆為正数得证d1 = d2.因d1| a 且d1| b 利用Corollary 1.1.2 我们知d1| a - bh = r. 因為d1| b, d1| r 且d2 = gcd(b, r) 故由Proposition 1.2.5 知d1| d2. 另一方面, 因為d2| b 且d2| r 故d2| bh + r = a. 因此可得d2| d1.Lemma 1.3.1 告诉我们当 a > b > 0 时, 要求a, b 的最大公因数我们可以先将 a 除以 b 所得餘数若為r, 则a, b 的最大公因数等於 b 和r 的最大公因数. 因為0r < b < a, 所以当然把计算简化了. 接著我们就来看看辗转相除法. 由於gcd(a, b) = gcd(- a, b) 所以我们只要考虑a, b 都是正整数的情况.Theorem 1.3.2 (The Euclidean Algorithm) 假设a, b 且 a > b. 由除法原理我们知存在h0, r0 使得a = bh0 + r0, 其中0r0 < b.若r0 > 0, 则存在h1, r1 使得b = r0h1 + r1, 其中0r1 < r0.若r1 > 0, 则存在h2, r2 使得r0 = r1h2 + r2, 其中0r2 < r1.如此继续下去直到rn = 0 為止. 若n = 0 (即r0 = 0), 则gcd(a, b) = b. 若n1, 则gcd(a, b) = rn - 1.証明. 首先注意若r0 0, 由於r0 > r1 > r2 > ... 是严格递减的, 因為r0 和0 之间最多仅能插入r0 - 1 个正整数, 所以我们知道一定会有nr0 使得rn = 0.若r0 = 0, 即 a = bh0, 故知 b 為 a 之因数, 得证 b 為a, b 的最大公因数. 若r0 > 0, 则由Lemma 1.3.1 知gcd(a, b) = gcd(b, r0) = gcd(r0, r1) = ... = gcd(rn - 1, rn) = gcd(rn - 1, 0) = rn - 1.现在我们来看用辗转相除法求最大公因数的例子Example 1.3.3 我们求 a = 481 和 b = 221 的最大公因数. 首先由除法原理得481 = 2 . 221 + 39, 知r0 = 39. 因此再考虑 b = 221 除以r0 = 39 得221 = 5 . 39 + 26, 知r1 = 26. 再以r0 = 39 除以r1 = 26 得39 = 1 . 26 + 13, 知r2 = 13. 最后因為r2 = 13 整除r1 = 26 知r3 = 0, 故由Theorem 1.3.2 知gcd(481, 221) = r2 = 13.在利用辗转相除法求最大公因数时, 大家不必真的求到rn = 0. 例如在上例中可看出r0 = 39 和r1 = 26 的最大公因数是13, 利用Lemma 1.3.1 马上得知gcd(a, b) = 13.在上一节Corollary 1.2.5 告诉我们若gcd(a, b) = d, 则存在m, n 使得 d = ma + nb. 当时我们没有提到如何找到此m, n. 现在我们利用辗转相除法来介绍一个找到m, n 的方法. 我们沿用Theorem 1.3.2 的符号. 首先看r0 = 0 的情形, 此时 d = gcd(a, b) = b 所以若令m = 0, n = 1, 则我们有 d = b = ma + nb. 当r0 0 但r1 = 0 时, 我们知d = gcd(a, b) = r0. 故利用a = bh0 + r0 知, 若令m = 1, n = - h0, 则d = r0 = ma + nb. 同理若r0 0, r1 0 但r2 = 0, 则知d = gcd(a, b) = r1. 故利用a = bh0 + r0 以及b = r0h1 + r1 知r1 = b - r0h1 = b - (a - bh0)h1 = - h1a + (1 + h0h1)b.因此若令m = - h1 且n = 1 + h0h1, 则 d = r1 = ma + nb. 依照此法, 当r0, r1 和r2 皆不為0 时, 由於d = gcd(a, b) = rn - 1 故由rn - 3 = rn - 2hn - 1 + rn - 1 知d = rn - 3 - hn - 1rn - 2. 利用前面推导方式我们知存在m1, m2, n1, n2 使得rn - 3 = m1a + n1b 且rn - 2 = m2a + n2b 故代入得d = (m1a + n1b) - hn - 1(m2a + n2b) = (m1 - hn - 1m2)a + (n1 - hn - 1n2)b.因此若令m = m1 - hn - 1m2 且n = n1 - hn - 1n2, 则 d = ma + nb.上面的说明看似好像当r0 0 时对每一个i {0, 1,..., n - 2} 要先将ri 写成ri = mia + nib, 最后才可将d = rn - 1 写成ma + nb 的形式. 其实这只是论证时的方便, 在实际操作时我们其实是将每个ri 写成mi'ri - 2 + ni'ri - 1 的形式慢慢逆推回d = ma + nb. 请看以下的例子.Example 1.3.4 我们试著利用Example 1.3.3 所得结果找到m, n 使得13 = gcd(481, 221) = 481m + 221n. 首先我们有13 = r2 = 39 - 26 = r0 - r1. 而r1 = 221 - 5 . 39 = b - 5r0, 故得13 = r0 - (b - 5r0) = 6r0 - b. 再由r0 = 481 - 2 . 221 = a - 2b, 得知13 = 6(a - 2b) - b = 6a - 13b. 故得m = 6 且n = - 13 会满足13 = 481m + 221n.要注意这裡找到的m, n 并不会是唯一满足 d = ma + nb 的一组解. 虽然上面的推演过程好像会只有一组解, 不过只能说是用上面的方法会得到一组解, 并不能担保可找到所有的解. 比方说若令m' = m + b, n' = n - a, 则m'a + n'b = (m + b)a + (n - a)b = ma + nb = d. 所以m', n' 也会是另一组解. 所以以后当要探讨唯一性时, 若没有充分的理由千万不能说由前面的推导过程看出是唯一的就断言是唯一. 一般的作法是假设你有两组解, 再利用这两组解所共同满足的式子找到两者之间的关系. 我们看看以下的作法.Proposition 1.3.5 假设a, b 且 d = gcd(a, b). 若x = m0, y = n0 是 d = ax + by 的一组整数解, 则对任意t , x = m0 + bt/d, y = n0 - at/d 皆為d = ax + by 的一组整数解, 而且 d = ax + by 的所有整数解必為x = m0 + bt/d, y = n0 - at/d 其中t 这样的形式.証明. 假设x = m, y = n 是 d = ax + by 的一组解. 由於已假设x = m0, y = n0 也是一组解, 故得am + bn = am0 + bn0. 也就是说a(m - m0) = b(n0 - n). 由於d = gcd(a, b), 我们可以假设 a = a'd, b = b'd 其中a', b' 且gcd(a', b') = 1 (参见Corollary 1.2.3). 因此得a'(m - m0) = b'(n0 - n). 利用b'| a'(m - m0), gcd(a', b') = 1 以及Proposition 1.2.7(1) 得b'| m - m0. 也就是说存在t 使得m - m0 = b't. 故知m = m0 + b't = m0 + bt/d. 将m = m0 + bt/d 代回am + bn = am0 + bn0 可得n = n0 - at/d, 因此得证 d = ax + by 的整数解都是x = m0 + bt/d, y = n0 -at/d 其中t 这样的形式. 最后我们仅要确认对任意t , x = m0 + bt/d, y = n0 - at/d 皆為d = ax + by 的一组整数解. 然而将x = m0 + bt/d, y = n0 - at/d 代入ax + by 得a(m0 + bt/d )+ b(n0 - at/d )= am0 + bn0 = d, 故得证本定理.利用Proposition 1.3.5 我们就可利用Example 1.3.4 找到13 = 481x + 221y 的一组整数解x = 6, y = - 13 得到x = 6 + 17t, y = - 13 - 37t 其中t 是13 = 481x + 221y 所有的整数解.欧几里得算法设计辗转相除法是利用以下性质来确定两个正整数 a 和 b 的最大公因子的:1. 若r 是 a ÷ b 的余数, 则gcd(a,b) = gcd(b,r)2. a 和其倍数之最大公因子为a。
解 二 元 一 次 方 程 — — — 拓 展 欧 几 里 得 算 法

欧几里得算法与扩展欧几里得算法(求二元一次不定方程、乘法逆元)1.欧几里得算法,即辗转相除法。
用于求两个整数的最大公约数比较方便,时间复杂度为O(logN)N为两个整数的规模。
最大公约数,是能够同时被两个整数整除的最大整数。
比如说,求56和21的最大公约数:(每行数分别代表a=56,b=21,a%b)此时得到最大公约数为7。
递归代码如下:int gcd(int a, int b)return b ? gcd(b, a%b) : a;2.扩展欧几里得算法顾名思义,扩展欧几里得算法就是对欧几里得算法的扩展,可以应用于求二元一次方程的通解、乘法逆元等。
对于上面的欧几里得算法,当递归到出口时,a=7,b=0。
很容易就可以得到一组ax+by=7的解:x=1,y=0。
那么如何通过7x+y=7的解逆推出56x+21y=7的解呢?对于欧几里得算法的每一个状态,都存在ax+by=gcd(a,b)的解,我们假设有这样两组解(且他们为相邻状态):ax1+by1=gcd(a,b)a'x2+b'y2=gcd(a',b')那么可以知道:a'=b b'=a%b 且gcd(a',b')=gcd(b,a%b)=gcd(a,b),所以有ax1+by1=bx2+(a%b)y2 另a%b可写为 a-a-b所以有 ax1+by1=bx2+(a-(a-b)b)y2故ax1+by1=ay2+bx2+(a-b)by2故ax1=ay2 by1 = b(x2+ (a-b)by2)故 x1=y2 y1 = x2 +(a-b)y2故可以得到x1,y1与x2,y2的关系 : x1=y2 y1 = x2 +(a-b)y2我们已知的是最后一组解,那么就要根据最后一组解逆推上去,就可以得到ax+by=gcd(a,b)的一组解了。
代码如下:int exgcd(int a, int b, intx, int y)return a;int r = exgcd(b, a%b, x, y); --递归到求出公约数,开始倒着求每一组的x,y。
扩展欧几里得算法以及求逆元的几种方法

扩展欧⼏⾥得算法以及求逆元的⼏种⽅法扩展欧⼏⾥得算法:ax+by=gcd(a,b)a x+by=gcd(a,b)a x+by=gcd(a,b)求出满⾜条件唯⼀的x,y的值设:设:设:r0=q1∗r1+r2r_{0}=q_{1}*r_{1}+r_{2}r0=q1∗r1+r2r1=q2∗r2+r3r_{1}=q_{2}*r_{2}+r_{3}r1=q2∗r2+r3r2=q3∗r3+r4r_{2}=q_{3}*r_{3}+r_{4}r2=q3∗r3+r4..............................rk−1=qk∗rk r_{k-1}=q_{k}*r_{k}r k−1=qk∗rk其中rk r_{k}r k就是最⼤公约数,因为rk r_{k}r k可由rk−1r_{k-1}r k−1和rk−2r_{k-2}r k−2,且rn=rn−2−qn−1∗rn−1r_{n}=r_{n-2}-q_{n-1}*r_{n-1}r n=rn−2−qn−1∗rn−1故rk−1r_{k-1}r k−1可表⽰为rk−2r_{k-2}r k−2和rk−3r_{k-3}r k−3的线性组合同理rk−2r_{k-2}rk−2也可向上表⽰。
这样得到最⼤公约数之后,⼀直向上回溯即可找到满⾜条件的x,y#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;ll ExGcd(ll a,ll b,ll &x,ll &y)//求 a b 最⼤公约数,且得到gcd(a,b)=x*a+y*b;{if(!b){x=1;y=0;return a;}ll gcd=ExGcd(b,a%b,x,y);ll temp,k;k=a/b;temp=x;x=y;y=temp-k*y;return gcd;}利⽤扩展欧⼏⾥得求⼀次同余⽅程形如式⼦a∗x=c (mod m)a*x=c\ \ \ (mod \ \ m)a∗x=c (mod m),求满⾜条件的x。
扩展的欧几里得算法

扩展的欧几里得算法扩展的欧几里得算法是一种求解最大公约数的算法,也被称为扩展欧几里得算法或扩展辗转相除法。
它不仅可以求出最大公约数,还可以求出一组使得两个数的线性组合等于最大公约数的系数。
本文将介绍扩展的欧几里得算法的原理、应用及其优化。
一、原理扩展的欧几里得算法是基于欧几里得算法(辗转相除法)的扩展。
欧几里得算法是一种求解最大公约数的方法,其基本思想是:用较小的数除较大的数,再用余数去除除数,如此反复,直到余数为零为止。
最后的除数就是最大公约数。
例如,求出48和18的最大公约数,过程如下:48 ÷ 18 = 2 (12)18 ÷ 12 = 1 (6)12 ÷ 6 = 2 0因此,最大公约数是6。
扩展的欧几里得算法的主要思想是在欧几里得算法的基础上,求出一组使得两个数的线性组合等于最大公约数的系数。
设a、b为两个正整数,d为它们的最大公约数,那么必定存在整数x和y,使得ax + by = d。
扩展的欧几里得算法就是通过辗转相除的过程,递归求解x和y的值。
具体来说,假设a、b为两个正整数,d为它们的最大公约数,且a > b。
则有:1. 如果b = 0,那么d = a,此时x = 1,y = 0。
2. 如果b ≠ 0,那么可以将a除以b,得到a = bq + r(其中q为a÷b的商,r为余数)。
因为d是a和b的公约数,所以d也是b和r的公约数。
因此,可以递归地求解b和r的系数x1和y1,即有:bx1 + ry1 = d由于a = bq + r,可以将其代入上式,得到:bx1 + (a - bq)y1 = d展开后得到:ay1 + b(x1 - qy1) = d因此,x = y1,y = x1 - qy1。
通过递归求解,最终可以得到x和y的值,从而求出a和b的最大公约数d以及一组使得两个数的线性组合等于最大公约数的系数。
二、应用扩展的欧几里得算法在密码学、数论、计算机图形学等领域都有广泛的应用。
用欧几里得扩展算法求67模119的逆元

用欧几里得扩展算法求67模119的逆元欧几里得扩展算法是一种求整数逆元的常用方法,逆元的概念在数论和密码学中经常被提及。
在本篇文章中,我将以从简到繁的方式来解释欧几里得扩展算法的原理和应用,帮助你更深入地理解这一概念。
一、欧几里得算法欧几里得算法,又称辗转相除法,是求两个正整数最大公约数的一种方法。
其基本原理是利用辗转相除的过程,即不断用较小的数去除较大的数,直到余数为0为止。
这时较大的数即为最大公约数。
以求119和67的最大公约数为例,进行辗转相除的过程如下:119 ÷ 67 = 1 (52)67 ÷ 52 = 1 (15)52 ÷ 15 = 3 (7)15 ÷ 7 = 2 (1)7 ÷ 1 = 7 0根据算法得到最大公约数为1。
二、扩展欧几里得算法扩展欧几里得算法不仅可以求出最大公约数,还可以找到一组整数x 和y,使得ax + by = gcd(a, b)。
在密码学中,扩展欧几里得算法常用于求解模的逆元。
以求67模119的逆元为例,我们需要找到一个整数x,满足67x ≡ 1 (mod 119)。
使用扩展欧几里得算法,我们可以求得x的值。
我们使用欧几里得算法求得最大公约数和辅助参数:119 ÷ 67 = 1 (52)67 ÷ 52 = 1 (15)52 ÷ 15 = 3 (7)15 ÷ 7 = 2 (1)7 ÷ 1 = 7 0根据算法,得到最大公约数为1,并且可以得到一组x和y的系数:7和(-1)。
我们可以得到67模119的逆元为7。
即67*7 ≡ 1 (mod 119)。
三、个人观点和理解欧几里得扩展算法是一种非常重要的算法,它不仅能够求出最大公约数,还可以在模运算中求出逆元。
在实际应用中,逆元的概念很常见,例如在密码学的RSA加密算法中就需要用到逆元来计算私钥。
通过学习欧几里得扩展算法,我们可以更好地理解模运算和逆元的概念,提高我们的数论和密码学知识水平。
快速指数取模运算与用扩展欧几里得算法求解最大公约数和求乘法逆元

y2 = t2;
y3 = t3;
}
}
int main()
{
int x, y, z ;
int a, b;
int *p, *q;
p = &x; q = &y;
z = 0;
printf("请输入两个数: ");
scanf("%d%d", &a, &b);
if (extended_Gcd(a,b, *p, *q) == 1)
{
x = 1;
y = 0;
retቤተ መጻሕፍቲ ባይዱrn a;
}
else
{
int gcd = extended_Gcd(b, a%b, x, y);
int t = x;
x = y;
y = t - (a / b) * y;
return gcd;
}
}
int extended_Ivn(int f, int d, int *result) //求乘法逆元
cout<<"........................................................."<<endl;
cout<<"请输入指数a:"<<endl;
cin>>a;
cout<<"请输入该基数b:"<<endl;
cin>>b;
cout<<"请输入被除数n:"<<endl;
{
int c=1;
do{
用扩展欧几里得算法求乘法逆元例题

用扩展欧几里得算法求乘法逆元例题扩展欧几里得算法是计算两个整数的最大公约数的算法,并且可以根据最大公约数得到一组解,用于求解线性同余方程的解,也可以用来求乘法逆元。
下面以求解$a$的乘法逆元为例,即寻找一个整数$x$,使得$a times x equiv 1 (text{mod} p)$,其中$p$是一个质数。
使用扩展欧几里得算法,先计算$a$和$p$的最大公约数$gcd(a,p)$,假设为$d$,则有:$gcd(a,p) = d = ax + py$,其中$x$和$y$是扩展欧几里得算法得到的一组解。
由于$d$是$a$和$p$的最大公约数,所以$d$必定是$a$的约数,即$d|a$。
同时,由于$p$是质数,所以$d$不可能是$p$的约数,即$d$与$p$互质。
因此,我们可以将等式两边同时除以$d$,得到:$dfrac{a}{d}x + dfrac{p}{d}y = 1$由于$d$与$p$互质,所以$dfrac{p}{d}$的乘法逆元存在,假设为$k$,即$dfrac{p}{d} times k equiv 1 (text{mod} d)$。
将$k$乘到等式两边,得到:$dfrac{a}{d} times k times x + dfrac{p}{d} times k times y = k$由于$dfrac{p}{d} times k equiv 1 (text{mod} d)$,所以可以将$dfrac{p}{d} times k$替换为$z$,得到:$dfrac{a}{d} times k times x + z times y = k$这个等式可以看成是一个线性同余方程$dfrac{a}{d} times k times x + z times y equiv k (text{mod} d)$,使用扩展欧几里得算法求解即可得到$x$的值。
总结一下求乘法逆元的步骤:1. 使用扩展欧几里得算法计算$a$和$p$的最大公约数$gcd(a,p)$,得到一组解$x$和$y$,使得$gcd(a,p) = ax + py$。
欧几里得算法

Euclid算法定义gcd(a,b)=gcd(b, a+kb) a,b,k为任意整数即gcd(a,b)=gcd(b, a mod b) a≥0,b>0• Example:gcd(55,22)=gcd(22, 55mod22)=gcd(22,11)=11证明:假定d=gcd(a,b),那么有d|a和d|b.对任何正整数b,a可表示为如下形式:a=kb+r ≡r mod b, a mod b =r , 因此,有(a mod b )= a-kb,k为某个整数。
但由于d|b,b也能整除kb, 而d|a,故有d|(a mod b), 这表明d 也是b 和(amod b) 的公因子。
由于这是可逆的,如果d 是b 和(a modb) 的公因子,那么d|kb,且d|[kb+(a mod b)],这等同于d|a。
这样a和b的公因子集合等同于b 和(a mod b) 的公因子集合。
编辑本段C语言的Euclid算法描述int gcd(int a,int b)//注释:两个数辗转相除。
a>b,如果a<b,需要将他们交换,这里不想写交换部分代码{if(a==0)return b;if(b==0)return a;return gcd(b,a%b);}编辑本段Euclid算法的应用求两个数的最大公约数gcd(55,22)=gcd(22, 55mod22)=gcd(22,11)=11最常用的就是在RSA里边求密钥RSA算法,是非对称加密的标准算法,其实算法很简单:找到两个素数p,q,再找一个数r,使gcd(r,(p-1)(q-1))=1,也就是说互素,然后再找一个数m,使rm=1(mod (p-1)(q-1)),然后再作乘法n=pq,然后把pq 丢掉,最好是让任何人都不知道,包括自己(免得说梦话的时候被人听到),然后手里拿到r,m,n,r就是Private Key,只有你知道,而m,n就是Public Key。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、实验1.1源代码:#include来自"stdio.h"
#include "stdlib.h"
#include "iostream"
using namespace std;
void Mode(int a, int b, int n)
{
int c=1;
do{
if(a%2==0)
return 1;
}
q = x3 / y3;
t1 = x1 - q*y1;
t2 = x2 - q*y2;
t3 = x3 - q*y3;
x1 = y1;
x2 = y2;
x3 = y3;
y1 = t1;
y2 = t2;
y3 = t3;
}
}
int main()
{
int x, y, z ;
int a, b;
int extended_Gcd(int a,int b, int &x, int &y) //求最大公约数
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
else
{
int gcd = extended_Gcd(b, a%b, x, y);
int t = x;
x = y;
y = t - (a / b) * y;
cout<<"请输入指数a:"<<endl;
cin>>a;
cout<<"请输入该基数b:"<<endl;
cin>>b;
cout<<"请输入被除数n:"<<endl;
cin>>n;
Mode(a,b,n);
}
二、实验效果图:
实验1.2用扩展欧几里得算法求解最大公约数和求乘法逆元
一、实验1.2源代码:
#include <stdio.h>
y3 = (f >= d) ? d : f;
while (1)
{
if (y3 == 0)
{
*result = x3; //两个数不互素则result为两个数的最大公约数,此时返回值为零
return 0;
}
if (y3 == 1)
{
*result = y2; //两个数互素则resutl为其乘法逆元,此时返回值为1
return gcd;
}
}
int extended_Ivn(int f, int d, int *result) //求乘法逆元
{
int x1, x2, x3, y1, y2, y3, t1, t2, t3, q;
x1 = y2 = 1;
x2 = y1 = 0;
x3 = (f >= d) ? f : d;
int *p, *q;
p = &x; q = &y;
z = 0;
printf("请输入两个数: ");
scanf("%d%d", &a, &b);
if (extended_Gcd(a,b, *p, *q) == 1)
{
extended_Ivn(a, b, &z);
printf("%d和%d互素,乘法的逆元是:%d\n", a, b, z);
}
else
{
z=extended_Gcd(a,b, *p, *q);
printf("%d和%d不互素,最大公约数为:%d\n", a, b, z);
}
return 0;
}
二、实验效果图:
{
a=a/2;
b=(b*b)%n;
}
else
{
a=a-1;
c=(b*c)%n;
}
}while(a!=0);
cout<<"取余结果为:"<<c<<endl;
}
void main ()
{
int a, b, n;
cout<<"输入格式范例b^a mod n"<<endl;
cout<<"........................................................."<<endl;