数论学习之扩展欧几里得

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数论学习之扩展欧几里得相关的知识,希望对你有一定的参考价值。

数论之扩欧

QB_UDG 201611811:34:40

  1. 1.       扩展欧几里德算法 
    用途:在已知整数a,b的情况下求不定方程ax+by=gcd(a,b)的一组整数解x,y;

原理: 

设 a*x1+b*y1=gcd(a, b); 
设 b*x2+(a%b)*y2=gcd(b, a%b); 

由欧几里德定理知: gcd(a, b)==gcd(b, a%b) 
所以==>a*x1+b*y1=b*x2+(a%b)*y2      
也就是==>a*x1+b*y1=b*x2+(a-(a/b)*b)*y2    
展开得到==>a*x1+b*y1=b*x2+a*y2-b*(a/b)*y2   
转换得到==>a*(x1)+b*(y1)=a*(y2)+b*(x2-(a/b)*y2)

观察上式可知,对于(a,b)的不定方程可以转换为(b,a%b)的不定方程 
x1=y2, y1=x2-a/b*y2 

从这里可以看出,x1,y1可以由下一步的x2,y2推出来,所以最初解可以在递归回溯的时候求解。
那什么时候是终止呢?也就是递归gcd(a, b)中b=0时 
即gcd(a, 0)此时 a*x+b*y==gcd(a, b)知 a*x+b*y=a 
解出x=1, y=0; 此时就是递归终止的地方。

代码实现:

int extended_ (int a, int b, int &x, int &y)

{

       int r, tmp;

       if (b==0) {  x = 1;  y = 0;  return a; }

       r = extended_gcd(b, a % b, x, y);

       tmp = x;  x = y;  y = tmp - a / b * y;

      return r;

}

应用: 
1.求ax+by=c的通解。

如果c%gcd(a,b)!=0) 则无解。 
若有解: 
先求出ax’+by’=gcd(a,b) 的一组解x’,y’; 
则原方程的一组解为x=x’*c/gcd(a,b),y=y’*c/gcd(a,b); 
若要求通解: 
因为ax+by=a(x+kb)+b(y-ka)=c; k是整数; 
所以原方程的通解为x=x+k*b,y=y-k*a;

2.解模线性方程 => ax ≡ b (mod n)

即ax%n=b%n 
转换为(ax-b)%n=0 也就是ax-b=ny 
所以也就转换为了求ax-ny=b的解;

3.乘法逆元

在同于方程的意义下,a的逆元常记为a-1,不是传统的指数概念, 
只是表示:a*a-1≡1(mod n) 
由前面的讨论可知:不定方程ax-ny=1要有解。 
这样1必须是gcd(a,n)的倍数,因此a和n必须互质,且ax≡1(mod n)只有唯一解,此解即为a在模n下的乘法逆元a-1 
注意:通过扩欧算出的不定方程有很多解,最终的逆元应该是x%n,也就是逆元的范围是[0,n-1] 
求ax≡1(mod n)的乘法逆元,若不存在,返回-1 
long long Inverse(long long a,long long n) 

long long x,y; 
if(extended_gcd(a,n,x,y)==1)return (x+n)%n; else return -1; 
}

在执行完extended_gcd()后,x可能为负数,加上n后将其变为整数。取 
模运算对于加、减、乘有分配率,但对除没有。 
乘法逆元可在同余式中把除法改为乘法。 
(a*b) mod p==((a mod p)*(b mod p)) mod p 
(a/b) mod p != ((a mod p)/(b mod p)) mod p 
但是我们可以把(a/b) mod p 改写成 (a*b-1) mod p 
((a/b)mod p==(a*b-1)mod p==((a mod p)*(b-1 mod p)) mod p

 

以上是关于数论学习之扩展欧几里得的主要内容,如果未能解决你的问题,请参考以下文章

ACM数论之旅4---扩展欧几里德算法(欧几里德(???)?是谁?)

数论集合

数论扩展欧几里得算法

《夜深人静写算法》数论篇 - (10) 扩展欧几里得定理

数论初步——扩展欧几里得算法

扩展欧几里德算法