中国剩余定理

中国剩余定理

  • 作用及内容
    可以用来求解n组线性同余方程的通解,例如有n个数a1,a2,a3an和n个两两互质的数m1,m2,m3mn组成的线性同余方程组的通解x=i=1naiMiMi1Mi1Mi的逆元)

{xa1(modm1)xa2(modm2)xa3(modm3)xan(modm3)

-数学证明
Mi=m1m2m3nmi,因为mi之间两两互质所以Mimi互质则Mi有逆元Mi1(modmi),则有MiMi11(modmi)
通解为:x=i=1naiMiMi1,任取i=k,由于除了MK,Mi都是mi的倍数所以Mi%mi=0则此时有
x=i=1naiMiMi1=akMkMk1符合方程,证毕。

扩展中国剩余定理

  • 作用
    与中国剩余定理类似,只不过可以处理mi之间不互质的情况。

{xa1(modm1)(1)xa2(modm2)(2)xa3(modm3)(3)xan(modm3)(n)

  • 内容及数学推导
    满足所有方程的x则必定得满足前两个方程,我们不妨先取前两个方程来看。(1)(2)k1m1+a1=k2m2+a2k1m1k2m2=a2a1,由欧几里得算法,当a2a1是gcd(m1,-m2)的倍数时k1,k2有解否则无解,如果此时无解则整个方程组必定无解。当有解时,由欧几里得算法,k1k1=(a2a1)gcd(m1,m2)通解为k1=k1+km2gdc(m1,m2)将通解代入方程(1)的等价式子中可得(x=k1m1+a1+km1m2gcd(m1,m2))k1m1+a1=m,k[m1,m2]=m,这样我们通过合并(1)(2)得到了一个类似与方程(1)(2)的新方程,我们可以重复这个过程n-1此就可以将n个方程合并为一个方程xa(modm),求解最小解x只需要求a%m,因为a和x在模m的情况下是相等的。
    -代码实现
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    LL d=exgcd(b,a%b,y,x);
    y=y-a/b*x;
    return d;
}
int main()
{
    int n;
    cin>>n;
    LL a1,m1;
    cin>>a1>>m1;
    for(int i=0;i<n-1;i++)
    {
        LL a2,m2;
        scanf("%lld %lld",&a2,&m2);
        LL k1,k2;
        LL d=exgcd(a1,a2,k1,k2);//应该传-a2的,但是为了保证d不为负数从而使得t不为负数,就传a2,而且后面更新也没用用到k2,所以对结果没有影响
        if((m2-m1)%d)
        {
            puts("-1");
            return 0;
        }
        k1=k1*(m2-m1)/d;
        LL t=a2/d;
        k1=(k1%t+t)%t;
        m1=k1*a1+m1;//注意先更新m1再更新a1
        a1=a1*a2/d;
        
    }
    printf("%lld",m1%a1);
    
    
    return 0;
}

  1. 补充知识:对于两个数a,b有:abgcd(a,b)=[a,b],[a,b]是a,b的最小公倍数,原理可联想小学求两个数的最小公倍数的方法,其实就是把两个数所有的因子相乘其中如果对于公因子就只乘一遍。 ↩︎

posted @   Taco_gu  阅读(49)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示