中国剩余定理 及 拓展中国剩余定理模板

45 篇文章 0 订阅
28 篇文章 0 订阅

求解同余方程组:
{ x ≡ r 1 ( m o d m 1 ) x ≡ r 2 ( m o d m 2 ) ⋯ x ≡ r n ( m o d m n ) \left\{\begin{matrix} x\equiv r_1 \pmod {m_1}\\ x\equiv r_2 \pmod {m_2}\\ \cdots\\ x\equiv r_n \pmod {m_n}\\ \end{matrix}\right. xr1(modm1)xr2(modm2)xrn(modmn)



①中国剩余定理


m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,,mn互质时,可用中国剩余定理解 x x x


M M M m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,,mn最小公倍数(LCM),由于各项互质,则有

M = ∏ i = 1 n m i M=\displaystyle\prod^n_{i=1}m_i M=i=1nmi

对于每一个同余方程,设一个 t i t_i ti,为同余方程 M m i t i ≡ 1 ( m o d m i ) \frac{M}{m_i}t_i\equiv 1\pmod {m_i} miMti1(modmi)最小非负整数解

则可解得同余方程组:

  • 特解 x = ∑ i = 1 n r i M m i t i x=\displaystyle\sum^n_{i=1}r_i\frac{M}{m_i}t_i x=i=1nrimiMti
  • 通解 X = x + k M          ( k ∈ Z ) X=x+kM\;\;\;\;(k\in Z) X=x+kM(kZ)
  • 最小非负整数解 x m i n = ( x m o d    M + M ) m o d    M x_{min}=(x\mod M+M)\mod M xmin=(xmodM+M)modM

模板:
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)    //拓展欧几里得 解单个同余方程
{
    if(b==0)
    {
        x=1;
        y=0;
        d=a;
    }
    else
    {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
LL r[maxn],m[maxn];
LL CRT()
{
    LL M=1,res=0;
    for(int i=1;i<=n;i++)
        M*=m[i];       //最小公倍数LCM
    LL a,b,d,x,y;
    for(int i=1;i<=n;i++)
    {
        a=M/m[i],b=m[i];
        exgcd(a,b,d,x,y);    //解同余方程:M/m[i] * t ≡ 1 (mod m[i])
                             //由于M/m[i]和m[i]互质,gcd恰为 1,所以一定有解
        x=(x%b+b)%b;         //最小非负整数解
        res=(res+r[i]*(M/m[i])*x)%M;   //加到特解当中
    }
    return res;
}


②拓展中国剩余定理


m 1 , m 2 , ⋯ &ThinSpace; , m n m_1,m_2,\cdots,m_n m1,m2,,mn不一定互质时,需用拓展中国剩余定理解 x x x


M k M_k Mk m 1 , m 2 , ⋯ &ThinSpace; , m k m_1,m_2,\cdots,m_k m1,m2,,mk(即前 k k k m m m)的 最小公倍数(LCM) k k k个方程组的一个特解为 x k x_k xk


对于 k k k个同余方程,设一个 t t t,为同余方程 x k − 1 + t ∗ M k − 1 ≡ r k ( m o d m k ) x_{k-1}+t*M_{k-1}\equiv r_k\pmod {m_k} xk1+tMk1rk(modmk)最小非负整数解

则有 x k = x k − 1 + t ∗ M k − 1 x_k=x_{k-1}+t*M_{k-1} xk=xk1+tMk1


递推可解得同余方程组:

  • 特解 x n x_n xn
  • 通解 X = x n + k M n &ThickSpace;&ThickSpace;&ThickSpace;&ThickSpace; ( k ∈ Z ) X=x_n+kM_n\;\;\;\;(k\in Z) X=xn+kMn(kZ)
  • 最小非负整数解 x m i n = ( x n m o d &ThinSpace;&ThinSpace; M n + M n ) m o d &ThinSpace;&ThinSpace; M n x_{min}=(x_n\mod M_n+M_n)\mod M_n xmin=(xnmodMn+Mn)modMn

模板:
void exgcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        d=a;
    }
    else
    {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
LL r[maxn],m[maxn];
LL EXCRT()
{
    LL M=m[1],res=r[1];
    LL a,b,c,d,x,y,t;
    for(int i=2;i<=n;i++)
    {                  //c转为正
        a=M,b=m[i],c=((r[i]-res)%m[i]+m[i])%m[i];
        exgcd(a,b,d,x,y);   //求解同余方程:t*M ≡ r[i]-x (mod m[i])
        if(c%d!=0)
        	return -1;      //无解
        t=b/d;
        x=x*c/d;
        x=(x%t+t)%t;
        res+=x*M;  //更新x
        M*=t;      //更新LCM:M = M*m[i]/gcd(M,m[i])
        res=(res%M+M)%M;
    }
    return res;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值