中国剩余定理 && 扩展中国剩余定理

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/niiick/article/details/80229217

中国剩余定理

问题

求解同余方程组
{x a1(mod  m1)x a2(mod  m2)x a3(mod  m3)...x ak(mod  mk)\begin{cases} x\equiv\ a_1(\mod m_1) \quad \\ x\equiv\ a_2(\mod m_2) \quad \\ x\equiv\ a_3(\mod m_3) \quad \\ ...\quad \\ x\equiv\ a_k(\mod m_k) \quad \\ \end{cases}
其中m1,m2,m3...mkm_1,m_2,m_3...m_k两两互质的整数
求x的最小非负整数解

定理

M=i=1kmiM=\prod_{i=1}^km_i,即M是所有mim_i的最小公倍数

tit_i为同余方程Mmiti 1(mod  mi)\frac{M}{m_i}t_i \equiv\ 1(\mod m_i)的最小非负整数解

则有一个解为x=i=1kaiMmitix=\sum_{i=1}^ka_i\frac{M}{m_i}t_i

通解为x+iM(iZ)x+i*M(i\in Z)
特别的,最小非负整数解为(x(x%M+M)M+M)%MM

证明

因为Mmi\frac{M}{m_i}是除mim_i之外的所有m的倍数
所以k̸=i,aiMmiti0(mod  mk)\forall k \not= i, a_i\frac{M}{m_i}t_i \equiv 0(\mod m_k)
又有Mmiti 1(mod  mi)\frac{M}{m_i}t_i \equiv\ 1(\mod m_i)
两边同时乘aia_iaiMmitiai(mod  mi)a_i\frac{M}{m_i}t_i \equiv a_i(\mod m_i)
带入x=i=1kaiMmitix=\sum_{i=1}^ka_i\frac{M}{m_i}t_i
原方程组成立
——算法竞赛进阶指南

代码实现

tit_i同余式的求解可以用扩展欧几里得

void exgcd(int a,int b,int &x,int &y)
{
    if(b==0){ x=1; y=0; return;}
    exgcd(b,a%b,x,y);
    int tp=x;
    x=y; y=tp-a/b*y;
}

int china()
{
    int ans=0,lcm=1,x,y;
    for(int i=1;i<=k;++i) lcm*=b[i];
    for(int i=1;i<=k;++i)
    {
        int tp=lcm/b[i];
        exgcd(tp,b[i],x,y);
        x=(x%b[i]+b[i])%b[i];//x要为最小非负整数解
        ans=(ans+tp*x*a[i])%lcm;
    }
    return (ans+lcm)%lcm;
}

一道模板题

洛谷P3868 [TJOI2009]猜数字 题解


扩展中国剩余定理

问题

求解同余方程组
{x a1(mod&ThinSpace;&ThinSpace;m1)x a2(mod&ThinSpace;&ThinSpace;m2)x a3(mod&ThinSpace;&ThinSpace;m3)...x ak(mod&ThinSpace;&ThinSpace;mk)\begin{cases} x\equiv\ a_1(\mod m_1) \quad \\ x\equiv\ a_2(\mod m_2) \quad \\ x\equiv\ a_3(\mod m_3) \quad \\ ...\quad \\ x\equiv\ a_k(\mod m_k) \quad \\ \end{cases}
其中m1,m2,m3...mkm_1,m_2,m_3...m_k不一定两两互质的整数
求x的最小非负整数解

求解

假设已经求出前k-1个方程组成的同余方程组的一个解为x
且有M=i1k1miM=\prod_{i-1}^{k-1}m_i
则前k-1个方程的方程组通解为x+iM(iZ)x+i*M(i\in Z)

那么对于加入第k个方程后的方程组
我们就是要求一个正整数t,使得
x+tMak(mod&ThinSpace;&ThinSpace;mk)x+t*M \equiv a_k(\mod m_k)

转化一下上述式子得
tMakx(mod&ThinSpace;&ThinSpace;mk)t*M \equiv a_k-x(\mod m_k)

对于这个式子我们已经可以通过扩展欧几里得求解t
若该同余式无解,则整个方程组无解
若有,则前k个同余式组成的方程组的一个解解为xk=x+tMx_k=x+t*M

所以整个算法的思路就是求解k次扩展欧几里得

lt exgcd(lt a,lt b,lt &x,lt &y)
{
    if(b==0){x=1;y=0;return a;}
    lt gcd=exgcd(b,a%b,x,y);
    lt tp=x;
    x=y; y=tp-a/b*y;
    return gcd;
}

lt excrt()
{
    lt x,y,k;
    lt M=bi[1],ans=ai[1];
    for(int i=2;i<=n;i++)
    {
        lt a=M,b=bi[i],c=(ai[i]-ans%b+b)%b;
        lt gcd=exgcd(a,b,x,y),bg=b/gcd;
        if(c%gcd!=0) return -1; 
        
        x=mul(x,c/gcd,bg);
        ans+=x*M;
        M*=bg;
        ans=(ans%M+M)%M;
    }
    return (ans%M+M)%M;
}

一道模板题

洛谷P4777 【模板】扩展中国剩余定理(EXCRT)

展开阅读全文

没有更多推荐了,返回首页