一、定义:中国剩余定理,又称中国余数定理,是数论中的一个关于一元线性同余方程组的定理,说明了一元线性同余方程组有解的准则以及求解方法。也称为孙子定理,古有“韩信点兵”、“孙子定理”、“求一术”(宋沈括)、“鬼谷算”(宋周密)、“隔墙算”(宋 周密)、“剪管术”(宋杨辉)、“秦王暗点兵”、“物不知数”之名。
二、引入:
一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
宋朝数学家秦九韶于1247年《数书九章》卷一、二《大衍类》对“物不知数”问题做出了完整系统的解答。明朝数学家程大位在《算法统宗》中将解法编成易于上口的《孙子歌诀》:
三人同行七十希,五树梅花廿一支,七子团圆正半月,除百零五便得知
这个歌诀给出了模数为3、5、7时候的同余方程的秦九韶解法。意思是:将除以3得到的余数乘以70,将除以5得到的余数乘以21,将除以7得到的余数乘以15,全部加起来后再减去105或者105的整数倍,得到的数就是答案(除以105得到的余数则为最小答案)。比如说在以上的物不知数问题里面,使用以上的方法计算就得到
70*2+21*3+15*2=233=210+23
因此按歌诀求出的结果就是23.
三、证明:
要证明中国剩余定理,首先,我们需要知道几个必须的公式,第一个呢,是在整数{Zm}(m表示所含整数个数)中,任一个M属于{Zm},都可写为:
M=(k1*m1)*(k2*m2)*.......*(ki*mi)
所以,当我们要求一个数A满足 ai=A mod mi时,可以写出一个对应关系{A双箭头(a1,a2,.....,ai)}
且此转换是唯一确定的,接下来,对于1<=i<=k,令Mi=M/mi,因为我们已知M=(k1*m1)*(k2*m2)*.......*(ki*mi),所以有Mi=0 mod mj;
定义 ci=Mi * (Mi(-1) mod mi) ——其中后半部分为Mi关于mi的逆元
A=(a1*c1+a2*c2+......+ai*ci) ( mod M)
设正整数两两互素,则同余方程组
有整数解。并且在模下的解是唯一的,解为
其中,而为模的逆元。
便可以求出以上等问题。
四、代码实现:
#A=(a1*c1+a2*c2+.......+ai*ci)(mod M)
#可使用 for i in range(1,n)将mi和ai的输入延申到n-1的范围
import gmpy2
m1=eval(input())
m2=eval(input())
m3=eval(input())
#由题意,a1=a3=,a2=
a1=eval(input())
a2=eval(input())
a3=eval(input())
M=m1*m2*m3
num1=gmpy2.invert(m2*m3,m1)
num2=gmpy2.invert(m1*m3,m2)
num3=gmpy2.invert(m2*m1,m3)
c1=a1*(M/m1)*num1
c2=c1+a2*(M/m2)*num2
c3=c2+a3*(M/m3)*num3
m=c3%M
print(m)