中国剩余定理及其扩展定理

一、中国剩余定理

image

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())

二、扩展中国剩余定理

image

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())
posted @ 2024-04-03 11:45  gebeng  阅读(86)  评论(0)    收藏  举报