以上算法中,b== 0 时,返回 a, x0= 1, y0= 0, 满足 a= a*x0+ b* y0。
b!= 0 时,算法先计算出 d= gcd( b, a% b ) 和 x, y,并且满足:
d= b* x0+ (a% b )* y0
所以, gcd(a,b)= gcd(b,a%b)= d= b* x0+ (a% b)* y0= b* x0+ ( a- [a/b]* b)* y0
= a* y0+ b* ( x0- [a/b]* y0 )= y0* a+ (x0- [a/b]* y0)* b
因此更新 x= y0, y= (x0+ [a/b]* y0) 可以满足等式 d= ax+ by,这样就证明算法的正确性。
定理二:同余方程 ax=b (mod n) 对于未知数 x 有解,仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。
证明比较复杂。不难得出,由这个定理可以推出以上的那个结论 gcd(a,b)= ax+ by 这样表示。
特别的,如果 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 。
定理三:设 d= gcd(a,n),假如整数 x 和 y,满足 d= ax+ ny(用扩展欧几里德得出)。如果 d| b,则方程
ax= b( mod n ) 的一个解为 x0= x* (b/ d ) mod n,且方程的 d 个解分别为 xi= x0+ i* (n/ d ) {i= 0... d-1}。
求解方程 ax= b (mod n ) 相当于求解方程 ax+ ny= b, (x, y为整数)
a* x0+ n* y0= d, 方程两边乘以 b/ d,(因为 d|b,所以能够整除),得到 a* x0* b/ d+ n* y0* b/ d= b。
所以 x= x0* b/ d,y= y0* b/ d 为 ax+ ny= b 的一个解,所以 x= x0* b/ d 为 ax= b (mod n ) 的解。
a* xi mod n= a( x0+ i* n/ d ) mod n
= ( a* x0+ a* i* n/ d ) mod n
= a* x0 mod n ( 因为 d| a )
= b。
pku 1061 青蛙的约会
由题意,我们设要跳 p 次才能相遇, 则有方程 (m- n)* p= y- x (mod L ),就是求解一个同余方程。
代码: