总结——数论:欧几里得算法&扩展欧几里得
一 欧几里得辗转相除法算法
设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 的公约数,则 d|b , d|r
又因 a=r+kb ,所以 d 为 a 的因子,即 d|a ,因此 d 是 a,b 的公约数。
综上,(a,b) 和 (b,a mod b) 的公约数一样,其最大公约数必然相等。
二 扩展欧几里得算法
如果 gcd(a,b)=d , 那么一定存在整数 x,y 满足 ax+by=d.
求出 x,y 的值就表示定理成立。注意因为这是一个不定方程,所以解不只有一组。如果大家有相关证明可以留言讨论。x,y 值的求解:
设存在 ax+by=gcd(a,b)
根据欧几里得定理 gcd(a,b)=gcd( b,a mod b) ,
可得 ax+by = gcd(a,b) = gcd(b,a mod b) = bx′+(a mod b)y′ = bx′+(a−b∗[a/b])y′ = ay' +b(x' - [a/b]y'),
可以看到,x,y 的值由 x',y' 得出。而 x',y' 又如何得到?递归。
重新来看看我们得到的两个等式。x 和 y 是 gcd(a,b)=ax+by 的解,而 x’ 和 y’ 是在对 gcd(a,b) 按欧几里德算法进行一步后的结果对应的贝祖等式 gcd(b,a mod b)=bx′+(a mod b)y′ 的解。也就是说,gcd(a,b) 对应的贝祖等式的解 x,y 可以由 gcd(b,a mod b) 对应等式的解x’,y’计算得出。
由于欧几里德算法最后一步为 gcd(d,0)=d,此时对应等式存在解 x=1,y=0, 因此只要如上述代码,从 gcd(d,0) 往前处理,在进行欧几里德算法的递归的时候根据相邻两次调用间 x,y 和 x’,y’ 的关系计算即可求出 ax+by=gcd(a,b) 的解。
方程通解:若(a,b)=1,且x0,y0为a*x+b*y=n的一组解,则该方程的任一解可表示为:x=x0+b*t,y=y0-a*t;且对任一整数t,皆成立。
三 扩展欧几里得算法的应用
①求解不定方程
pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。
有整数解的条件:c|gcd(p,d)。
②求解模线性方程(线性同余方程)ax≡b (mod n) 的最小解
同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。
求解方程 ax≡b (mod n) 相当于求解方程 ax+ ny= b(x, y为整数)
设 ax+ny=gcd(a,n) 的解为 x0,y0,则 ax+ny=b 的解为 x=x0*b/gcd(a,n)
要求其最小整数解,可根据同解x = x0 + n/gcd(a,n) * t;
设 s = n / gcd(a,n),x%s得到最一个值x1,x1可能为负数,此时x%s还需要+s,加上s后可能就不是最小值了,所以还需要在对s取余
所以最小(整数)解为 x = (x % s + s) % s
③求解模的逆元
同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。这时称求出的 x 为 a 的对模 n 乘法的逆元。
对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程 ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。
求 gcd(a,b) 的代码:
//递归 int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } //迭代 int Gcd(int a, int b){ while(b != 0){ int r = b; b = a % b; a = r; } return a; }
求解 ax+by=gcd(a,b)=d 的解 x,y 的代码如下:
void exgcd(int a,int b,int & d,int & x,int & y){ if (b==0) {x=1;y=0;d=a;return;} exgcd(b,a%b,d,y,x); y-=x*(a/b); }

浙公网安备 33010602011771号