数论复习之扩欧

数论复习之扩欧

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_gcd(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

你可能感兴趣的:(数论复习)