一、中国剩余定理

from functools import reduce
r = [2,3,2]
# 要求mod里的数必须两两互质
mod = [3,5,7]
def exgcd(a,b):
if b == 0:
return 1,0,a
x,y,gcd = exgcd(b,a % b)
x,y = y,(x - (a // b) * y)
return x,y,gcd
m0 = reduce(lambda x,y:x * y,mod,1)
# print(m0)
def crt():
ans = 0
for i,x in enumerate(mod):
m = m0 // x
inv,_,_ = exgcd(m,x) # m * inv ≡ 1 (mod x)
inv %= x
# print(inv,m,x)
ans = (ans + r[i] * inv * m) % m0
return ans % m0
print(crt())
二、扩展中国剩余定理

n = 3
r = [2,3,2]
m = [3,5,7]
def exgcd(a,b):
if b == 0:
return 1,0,a
x,y,gcd = exgcd(b,a % b)
x,y = y,(x - (a // b) * y)
return x,y,gcd
# n个同余方程合并(n - 1)次
def excrt():
if n == 1:
if r[0] >= m[0]:
return -1
return r[0]
for i in range(1,n):
x,y,gcd = exgcd(m[0],m[i])
# python不需要考虑出现负数取余的情况
if (r[i] - r[0]) % gcd != 0:
return -1
# 特解
x = x * (r[i] - r[0]) // gcd
# 通解:X = x + (m[i] // gcd) * k
x = x % (m[i] // gcd)
# 新余数
r[0] = m[0] * x + r[0]
# m[0]变成lcm(m[0],m[i])
m[0] = m[0] * m[i] // gcd
# 对m[0]取余,防止太大
r[0] %= m[0]
return r[0] % m[0]
print(excrt())