前置准备知识:逆元
这个名字乍一听很牛逼,但其实就是代数系统里学过的那个逆元,只不过是模得1的逆元。在这里我们只是来介绍一下拓展欧几里得求逆元方法。P * P^-1 = 1 (mod Q)
注意:我们这里的余数都是 P*n - Q*m得到的数,m,n是正整数。(负数也适用)
假设我们要求 5 * X = 1 (mod18),那么我们先要清楚模数和被模数之间的分解,如下:
18 = 5 * 3 +3; 这样分解,将模数与被模数中较大的用另一个表示,一步步大化小,直到找到1为止。
18 = 5 * 3 +3 ->
5 = 3 * 1 + 2 这里因为上一步余数是3,3<5,所以变成了没被分解的5与余数3的分解 ->
5 = 2 * 2 + 1 这里因为余数为2,2<5,所以5被2分解,余1,结束。
当我们找到这个1时,也就是题目要求的P * P^-1 = 1 (mod Q)中的1。这怎么理解呢?接着往下看
我们把刚才的式子一步步往回推,5 = 2 * 2 + 1 ,这个2其实就是 5-3 * 1得到的,带入。
5 = 2 * (5 - 3 * 1) + 1 然后这个3又是上一步(18 - 5 * 3) 得到的,带入
5 = 2 * (5 - (18 - 5 * 3) * 1) +1 得到的 推到这里,看出来了吗,所有元素都是P Q组成的,移项之后得到 1 = -7 * 5 + 2 * 18
所以P^-1 就是-7 若要求正整数,就是18+(-7) = 11
中国剩余问题
假设有一个数X满足:
X == 2(mod 3)
X == 3(mod 5)
X == 2(mod 7)
求X是多少?
这道题我们直接给出解法,在求解中解释。
首先,化X == (M1 * M1^-1 * b1 + M2 * M2^-1 * b2 + M3 * M3^-1 * b3)% M
其中M1,M2, M3分别是1,2,3式中除本身外另外两个式子模数的乘积。如
M1 = 7 * 5 = 35
M2 = 3 * 7 = 21
M3 = 3 * 5 = 15
b1,b2,b3分别是每个式子的余数,分别是2,3,2
M1^-1,M2^-1,M3^-1 则分别是M1 M2 M3的逆元,也就是Mi模原式子模数后得到1。
M则是所有式子中模数之积,M = 3 * 5 * 7 = 105
我们根据扩展欧几里得算法得到三个式子逆元分别是 2 , 1, 1
所以 X == 35 * 2 * 2 + 21 * 3 * 1 + 15 * 2 * 1 mod 105
X == 23
仔细想想这个解法巧妙在Mi * Mi^-1 * bi保证了模剩下两个都能模开同时剩下 bi,三个这样的数字相加再取总模,结果肯定是对的。也算是对(A + B + C)mod D = (A mod D + B mod D + C mod D) mod D的最好应用。