中國剩餘定理 及 拓展中國剩餘定理模板

求解同餘方程組:
{xr1(modm1)xr2(modm2)xrn(modmn)\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.



①中國剩餘定理


m1,m2, ,mnm_1,m_2,\cdots,m_n互質時,可用中國剩餘定理解xx


MMm1,m2, ,mnm_1,m_2,\cdots,m_n最小公倍數(LCM),由於各項互質,則有

M=i=1nmiM=\displaystyle\prod^n_{i=1}m_i

對於每一個同餘方程,設一個tit_i,爲同餘方程 Mmiti1(modmi)\frac{M}{m_i}t_i\equiv 1\pmod {m_i}最小非負整數解

則可解得同餘方程組:

  • 特解x=i=1nriMmitix=\displaystyle\sum^n_{i=1}r_i\frac{M}{m_i}t_i
  • 通解X=x+kM        (kZ)X=x+kM\;\;\;\;(k\in Z)
  • 最小非負整數解xmin=(xmod  M+M)mod  Mx_{min}=(x\mod M+M)\mod M

模板:
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;
}


②拓展中國剩餘定理


m1,m2,&ThinSpace;,mnm_1,m_2,\cdots,m_n不一定互質時,需用拓展中國剩餘定理解xx


MkM_km1,m2,&ThinSpace;,mkm_1,m_2,\cdots,m_k(即前kkmm)的 最小公倍數(LCM)kk個方程組的一個特解爲xkx_k


對於 kk個同餘方程,設一個tt,爲同餘方程 xk1+tMk1rk(modmk)x_{k-1}+t*M_{k-1}\equiv r_k\pmod {m_k}最小非負整數解

則有xk=xk1+tMk1x_k=x_{k-1}+t*M_{k-1}


遞推可解得同餘方程組:

  • 特解xnx_n
  • 通解X=xn+kMn&ThickSpace;&ThickSpace;&ThickSpace;&ThickSpace;(kZ)X=x_n+kM_n\;\;\;\;(k\in Z)
  • 最小非負整數解xmin=(xnmod&ThinSpace;&ThinSpace;Mn+Mn)mod&ThinSpace;&ThinSpace;Mnx_{min}=(x_n\mod M_n+M_n)\mod M_n

模板:
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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章