欧几里得算法与同余方程
欧几里得算法
说起数学家不得不提起欧几里得,而欧几里得的欧几里得算法(gcd)直到现在仍在计算机与数学领域有着卓越的贡献
欧几里得算法非常简单,简而言之就是gcd(a,b)=gcd(b,a%b)。如果你是小升初时学奥数的受害者,那你一定会很眼熟:这不是辗转相除法吗!! 是的其实你早就接触过这个算法了,而求出最小公约数只是这个算法的最最基本的用法(当然也用的最多),但在算法这个版块里,它的用法基本就不同了。
证明方法(以下摘自百度百科)
证法一
证法二
裴蜀定理
欧几里得算法不仅仅用于求最大公约数,还可以用于求出形如ax+by=c,a mod b = c(这二者本质上是相差不大的)的解。当然只凭借欧几里得算法是不够的,这里补充一个数学定理,裴蜀定理
(以下摘自百度百科)
裴蜀定理说明了对任何整数a、b和它们的最大公约数d ,关于未知数 x 和 y 的线性丢番图方程(称为裴蜀等式)。
(1)若b=0,则(a,b)=a.这时定理显然成立。
(2)若a,b不等于0.
∵(a,b)=(a,-b)∴不妨设a,b都大于零,a>=b,(a,b)=d
对ax+by=d,两边同时除以d,可得(a1)x+(b1)y=1,其中(a1,b1)=1。
转证(a1)x+(b1)y=1。由带余除法:
a1=(q1)b+(r1),其中0=<r1<b1
b1=(q2)(r1)+(r2),其中0=<r2<r1
(r1)=(q3)(r2)+(r3),其中0=<r3<r2
.....
(rn-3)=(qn-1)(rn-2)+(rn-1)
(rn-2)=(qn)(rn-1)+(rn)
(rn-1)=(qn+1)(rn)
于是,有(a1,b1)=(b1,r1)=(r1,r2)=...=(rn-1,rn)=1
故
(rn-2)=(xn)(rn-1)+1
即1=(rn-2)-(xn)(rn-1)
由倒数第三个式子(rn-1)=(rn-3)-(xn-1)(rn-2)代入上式,得
1=[1+(xn)(xn-1)](rn-2)-(xn)(rn-3)
然后用同样的办法用它上面的等式逐个地消去(rn-2),...(r1),
可证得1=(a1)x+(b1)y。
(这两个定理证明看不懂或不看都无所谓,会用就行)
拓展欧几里得算法
题目描述
求关于x的同余方程ax≡1(modb) 的最小正整数解。
输入格式
一行,包含两个正整数 a,b,用一个空格隔开。
输出格式
一个正整数x0,即最小正整数解。输入数据保证一定有解。
这道题不难,但是扩欧的很经典的用法,这里略过暴力直接讨论正解,
很显然这道题可以转化为ax+by=1的最小正整数解,那么就可以从这个角度入手。首先看到欧几里得算法,gcd(a,b)=gcd(b,a%b),又由裴蜀定理可得ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(a%b)y2。a%b可以换一种等价的表达方式即a-a/b*b(a/b取整) ,然后方程就可以变形为ax1+by1=ay2 +b(x2−(a/b)y2 )从而推出x1=y2,y1=x2−(a/b)y2。所以由一组解可以推出无数组解。而有一组解必然为x=1,y=0(其实当欧几里得算法运行至b=0时,与y没得关系)。然后最后对x进行一下处理使其成为方程的最小正整数解。
代码如下
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 long long int x,y; 5 int exgcd(int a,int b) 6 { 7 if(b==0) 8 { 9 x=1; 10 y=0; 11 return 0; 12 } 13 exgcd(b,a%b); 14 long long int t; 15 t=x; 16 x=y; 17 y=t-(a/b)*y; 18 return 0; 19 } 20 int main() 21 { 22 int a,b; 23 cin>>a>>b; 24 exgcd(a,b); 25 while(x<b) 26 x+=b; 27 cout<<(x+b)%b; 28 }
总结
扩欧不难,且很有用(而且还要考)

浙公网安备 33010602011771号