中国剩余定理(crt)和扩展中国剩余定理(excrt)

中国剩余定理(crt)

crt是用来对于一个一元线性同余方程求解的算法:

 其中 m 1,m2​,m3​...mk​为两两互质的整数
定理:

我们设  M= \prod_{i=1}^{n}m_{i}  ,设   M_{i}=M/m  设  t_{i} = M_{i}^{-1}为  M_{i}m_{i} 意义下的逆元.

这个一元线性同余方程组的通解为:

x=\left ( \sum_{i=1}^{n}a_{i}t_{i}M_{i} \right )mod M

证明(来自百度百科):

下面上板子题:

【模板】中国剩余定理(CRT)/ 曹冲养猪 - 洛谷https://www.luogu.com.cn/problem/P1495

#include<bits/stdc++.h>
#define int long long
int a[20],b[20];
void exgcd(int a,int b,int& x,int& y)
{
	if(!b)
    {
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,y,x);
	y-=a/b*x;
}
int inv(int a,int b)
{
    int x,y;
    exgcd(a,b,x,y);
    return (x%b+b)%b;
}
int ksc(int a,int b,int p)
{
    int res=0;
    while(b)
    {
        if(b&1)
            res=(res+a)%p;
        a=(a+a)%p;
        b>>=1;
    }
    return res;
}
void solve()
{
    int n,M=1,ans=0;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i],&b[i]);
        M=M*a[i];
    }
    for(int i=1;i<=n;i++)
    {
        int m=M/a[i];
        int invm=inv(m,a[i]);
        ans=(ans+ksc(ksc(invm,M/a[i],M),b[i],M))%M;
    }
    printf("%lld\n",ans);
    return ;
}
signed main()
{
    solve();
    return 0;
}

扩展中国剩余定理(excrt)

拓展crt的作用也是求解下列方程组,但是约束条件不同:

 其中 m 1,m2​,m3​...mk​为不一定两两互质的整数.

我们每次选出两个方程利用exgcd进行合并即可,具体推算过程如下:

依照上面的证明两两结合,最后把全部结合即可.

证明完毕,来板子题耍耍:

【模板】扩展中国剩余定理(EXCRT) - 洛谷https://www.luogu.com.cn/problem/P4777

#include<bits/stdc++.h>
#define int long long
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=(a/b*x);
    return d;
}
int mul(int a,int b,int mod)
{
    int res=0;
    while(b>0)
    {
        if(b&1) res=(res+a)%mod;
        a=(a+a)%mod;
        b>>=1;
    }
    return res;
}

void solve()
{
    int n;
    scanf("%lld",&n);
    int a1,m1,a2,m2;
    scanf("%lld%lld",&m1,&a1);
    for(int i=2;i<=n;i++)
    {
        scanf("%lld%lld",&m2,&a2);
        int k1,k2;
        int d=exgcd(m1,m2,k1,k2);
        int c=((a2-a1)%m2+m2)%m2;
        if(c%d)
        {
            /*无解*/   
        }
        k1=mul(k1,c/d,m2/d);
		a1=a1+k1*m1;
		m1=abs(m1/d*m2);
    }
    printf("%lld\n",(a1%m1+m1)%m1);
    return ;
}
signed main()
{
    solve();
    return 0;
}

<think>好的,我需要回答用户关于中国剩余定理的压缩实现或算法的问题。首先,我要确保自己对中国剩余定理CRT)有足够的理解。中国剩余定理是数论中的一个重要定理,用于解决一组同余方程的问题,特别是在模数两两互质的情况下,可以找到一个唯一的解模这些模数的乘积。 接下来,用户提到了“压缩算法实现”。这里的“压缩”可能指的是如何高效或优化地实现CRT,尤其是在处理多个同余方程时,如何合并这些方程,减少计算量或存储空间。我需要考虑现有的CRT实现方法,尤其是扩展中国剩余定理exCRT),它处理模数不互质的情况,这可能与用户的问题相关。 根据参考内容,引用[3]提到了扩展中国剩余定理exCRT),这可能对处理非互质模数有帮助。因此,我需要解释exCRT的基本步骤,以及如何通过递推合并方程来逐步求解,这可能是压缩实现的一部分。 另外,用户可能关心的是如何优化存储或计算步骤。例如,在合并两个同余方程时,如何有效计算模数余数,避免重复计算或减少中间变量的存储。这可能涉及到数学上的优化,比如利用贝祖定理求解线性同余方程,或者处理模数不互质时的调整。 我还需要考虑代码实现,用户可能希望看到具体的算法步骤或代码示例。但根据系统级指令,代码必须用正确的格式,并且用户要求的是压缩实现,所以可能需要展示一个高效的算法结构,比如循环合并方程,每次处理两个方程,直到所有方程合并完成。 另外,引用[2]提到空间复杂度的重要性,因此在实现时需要考虑如何减少内存使用。例如,在合并过程中逐步更新当前的解模数,而不是保留所有中间结果,这样可以节省空间。 需要验证的是,合并过程中的每一步是否正确,如何处理模数不互质的情况,以及如何确保解的存在性。例如,当两个方程的解不满足合并条件时,整个系统无解,此时需要抛出错误或处理异常。 最后,生成相关问题需要考虑用户可能进一步感兴趣的方面,比如exCRT的应用场景、优化方法的时间复杂度,或者与其他数论问题的结合,如引用[3]提到的斐波那契数列的循环节问题。 总结来说,我需要分步骤解释中国剩余定理的压缩实现,可能包括exCRT的递推合并方法,代码示例,以及优化存储计算的策略,同时引用相关参考文献,并生成相关问题。</think>### 中国剩余定理的压缩实现 中国剩余定理CRT)用于求解同余方程组: $$x \equiv a_1 \pmod{m_1} \\ x \equiv a_2 \pmod{m_2} \\ \vdots \\ x \equiv a_n \pmod{m_n}$$ 当模数两两互质时,存在唯一解模$M = m_1 \cdot m_2 \cdots m_n$。 **压缩实现的核心在于逐步合并方程,减少重复计算**,尤其在模数不互质时需使用扩展中国剩余定理exCRT)[^3]。 --- #### 算法步骤(exCRT递推合并) 1. **初始化**:令当前解$x = a_1$,当前模数$M = m_1$。 2. **逐次合并**: - 对第$i$个方程$x \equiv a_i \pmod{m_i}$,需满足: $$x + k \cdot M \equiv a_i \pmod{m_i} \quad (k \text{为整数})$$ - 化简为线性同余方程: $$k \cdot M \equiv a_i - x \pmod{m_i}$$ - 用扩展欧几里得算法求$k$,若无解则整个系统无解。 - 更新解模数: $$x' = x + k \cdot M \\ M' = \text{lcm}(M, m_i)$$ 3. **最终解**:$x \bmod M'$。 --- #### 代码实现(Python) ```python def exCRT(a_list, m_list): from math import gcd x, M = 0, 1 # 初始解模数 for ai, mi in zip(a_list, m_list): d = gcd(M, mi) if (ai - x) % d != 0: return -1 # 无解 # 解方程 k*M ≡ (ai - x) (mod mi) _, k, _ = extended_gcd(M, mi) k *= (ai - x) // d x += k * M M = (M * mi) // d # 更新为最小公倍数 x %= M # 保持最小非负解 return x def extended_gcd(a, b): if b == 0: return a, 1, 0 else: g, x, y = extended_gcd(b, a % b) return g, y, x - (a // b) * y ``` --- #### 优化与压缩 1. **空间优化**:仅维护当前解$x$模数$M$,无需存储所有中间结果[^2]。 2. **计算优化**:使用递推合并代替递归,减少栈空间占用。 3. **并行化潜力**:若方程分组互质,可分组并行合并后再次合并。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值