# 算法介绍

$(S):\begin{cases} x \equiv a_1 \; (mod \; m_1) \\ x \equiv a_2 \; (mod \; m_2) \\ \cdots \\ x \equiv a_n \; (mod \; m_n) \end{cases}$

1. $$M = \prod_{i=1}^{n} m_i$$，是整数 $$m_1, m_2, \cdots ,m_n$$ 的乘积，并设 $$M_i = M / m_i$$ 是除 $$m_i$$ 以外的 $$m$$ 个数的乘积
2. $$t_i = M_i^{-1}$$$$M_i$$$$m_i$$ 的逆元，$$t_i M_i \equiv 1 \; (mod \; m_i)$$
3. 方程组 $$(S)$$ 的通解形式为

$x = \sum_{i=1}^{n} a_i t_i M_i \; (mod \; M)$

# 具体代码(python)

def ex_gcd(a: int, b: int) -> (int, int, int):
"""
:return: gcd x y
"""
if a == 0 and b == 0:
return None
else:
x1, y1, x2, y2 = 1, 0, 0, 1  # 初始化x1,y1,x2,y2
while b:
q, r = divmod(a, b)
a, b = b, r  # gcd(a,b)=gcd(b,a%b)
x1, y1, x2, y2 = x2, y2, x1 - q * x2, y1 - q * y2
# 返回一个三元组，依次是(gcd,x,y)，使得 xa+yb=gcd
return (a, x1, y1) if a > 0 else (-a, -x1, -y1)

def crt(r_lst: list, m_lst: list):
"""
:param r_lst: 余数列表
:param m_lst: 模数列表
:return: 同余式的解 x
"""
r_lst = [r % m for (r, m) in zip(r_lst, m_lst)]  # 预先初始化
M, res = 1, 0
# M = m1*m2*...*mn
for m in m_lst:
M = M * m
for r, m in zip(r_lst, m_lst):
temp = r * M // m * ex_gcd(M // m, m)[1]
res = (res + temp) % M
return res


# 测试样例及结果

#样例一
r1 = 0
r2 = 0
r3 = 0

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 0

#样例二
r1 = 5
r2 = 20
r3 = 34

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 19900

#样例三
r1 = 283
r2 = 102
r3 = 23

m1 = 23
m2 = 28
m3 = 33
# 结果
x = 9230

# 样例四
r1 = 802310684485241212312289432691586430708135062249
r2 = 961714109955647014172499578071923389425123540027
r3 = 1381194006087304024683552712488022595194097928701

m1 = 489808178709479466279507878773770708214878979673
m2 = 896234965496726578561614071442814700467907036641
m3 = 1213827005758305602466882992172310409456053868843
# 结果
x = 509678885274099350362023393352578082708427568899031846709831030150136786034479833877558685987430752184856829540175601138538702893016912367204417

# 样例五
r1 = 8157969540288411637818433039558323184074779086100165504668538221920170369774913261335059602331627321130656458962980224196880533337839226059601303464776145
r2 = 9699616044315021194953572561076502992783130623216574220426043600142343504101508838526221359049417564415801914072315788919275792502477693022853881785198116
r3 = 7832693802256371667866514213119452199821916193668106904135812283217637737600922381702016472708855675649121271702977408217814917908566132517503707494037556

m1 = 13392316081651420877308875276166772808601812122052371442339078877740399569281672683820206196320955005869072002883847646526584107260355414977120453263391947
m2 = 9734466939658282823343760206593283968765904848250021580218634383869090913086348857668999272399075016287736914000854272239315769632719896968098820774563511
m3 = 9460200357790728398862913232664036038694521858415765931064505193755202156521446156499075450033429983317127589636591133111239548821251790171694322930011927
# 结果
x = 140572312041533061939584609644717750021442788242435867722409828434892657662537831184923189181096394076478262531889424668688702308599804777751973228204825311287964733040400616834339634575632758809487770732820709381703577738588480472947498776340910097209045550068926957348504285471095081384232331643227847899239


# 用途

posted @ 2021-07-07 16:58  kentle  阅读(924)  评论(0编辑  收藏  举报