数论 中国剩余定理

中国剩余定理(Chinese Remainder Theorem)

定义

又名孙子定理,最早出现在《孙子算经》中

对于下面的一元线性同余方程组:

\[\begin{equation} \left\{ \begin{aligned} &x\equiv a_1\pmod {m_1}\\ &x\equiv a_2\pmod {m_2}\\ &\ \ \ \ \ \vdots\\ &x\equiv a_n\pmod{m_n} \end{aligned} \right. \end{equation} \]

中国剩余定理给出了其有解的判定条件及解集

判定条件: \(m_1,m_2,\dots,m_n\) 两两互质

通解:

  1. \(M=\prod\limits_{i=1}^nm_i,M_i=\frac M{m_i}\)

  2. \(t_i\)\(M_i\)\(m_i\) 的逆元

  3. 方程组通解的形式就为:

    \[\begin{align} \notag x&=a_1t_1M_1+a_2t_2M_2+\dots+a_nt_nM_n\pmod M\\\notag &=\sum_{i=1}^na_it_iM_i\pmod M \end{align} \]

证明

证明: \(x=\sum\limits_{i=1}^na_it_iM_i\) 是方程组的一个解

\[\begin{align} \notag&\because\ \forall i,j\in\{1,2,\dots,n\},i\not=j,\\\notag &有\ \gcd(m_i,m_j)=1\\\notag &\Rightarrow\exist t_i\equiv M_i^{-1}\pmod {m_i}\\\notag &设\ x=a_1t_1M_1+a_2t_2M_2+\dots+a_nt_nM_n\\\notag &\therefore\ x\%m_i=\sum_{j=1}^n(a_jt_jM_j\%m_i)\\\notag &\because\forall\ j\in\{1,2,\dots,n\},j\not=i,\exist\ m_i|M_j\\\notag &\therefore\ x\%m_i=a_it_iM_i\%m_i\\\notag &\because\ t_i\equiv M_i^{-1}\pmod {m_i}\\\notag &\therefore\ t_iM_i=1\pmod {m_i}\\\notag &\therefore\ x\%m_i=a_i\\\notag &\therefore\ x是方程组的解 \end{align} \]

证明: \(x=kM+\sum\limits_{i=1}^na_it_iM_i\) 是方程组的通解

\[\begin{align} \notag&设\ x_1.x_2都是方程组的解\\\notag &\forall\ i\in\{1,2,\dots,n\}\\\notag &有\ x_1\%m_i=a_i,x_2\%m_i=a_i\\\notag &\therefore\ x_1\%m_i-x_2\%m_i=(x_1-x_2)\%m_i\\\notag &\ \ \ \ \ \ =a_i-a_i=0\\\notag &\therefore\ m_i\ |\ (x_1-x_2)\\\notag &\because\ m_1,m_2,\dots,m_n\ 两两互质\\\notag &\therefore\ \prod_{i=1}^nm_i\ |\ (x_1-x_2)\Rightarrow\ M\ |\ (x_1-x_2)\\\notag &\therefore\ 两个解至少相差 M,得证 \end{align} \]

用法

\(O(n\log n)\)

typedef long long lld;
const int maxn=10+12;
lld a[maxn],m[maxn],M=1;
int n;
//exGcd
lld gcd(lld a,lld b,lld&x,lld&y){
    if(b==0){
        x=1;y=0;return a;
    }
    lld g=gcd(b,a%b,y,x);
    y=y-a/b*x;
    return g;
}

lld crt(lld a[],lld m[]){
    lld ans=0,t,y;//t refers to M/m[i]'s Inverse Element
    for(int i=1;i<=n;i++){
        gcd(M/m[i],m[i],t,y);//M refers to \prod_{i=1}^n(m[i])
        //M should be preprocessed
        //use exGcd to get Inverse Element
        //now t is M/m[i]'s Inserse Element
        ans=(ans+(M/m[i]*t*a[i])%M+M)%M;//According to the formula
        //Explian: why wo should use "(M/m[i]*t*a[i])%M+M"
        //that is to avoid negative numbers
        //we know that (x+M) is still the solution of the system of equations
        //when x is a negative number
        //x%M is a negative number between (-M,0)
        //so x%M+M is a positive number between (0,M)
        //in this way we could make sure that the answer is what we need
    }
    return ans;
}

ex-CRT

定义

扩展中国剩余定理,是对中国剩余定理的一个补充,用于解决中国剩余定理中模数 \(m_i\) 不互质的情况。

中国剩余定理的限制

中国剩余定理对下面的这个方程组 \(S\)

\[\begin{equation} S=\left\{ \begin{aligned} x&\equiv a_1\pmod {m_1}\\ x&\equiv a_2\pmod{m_2}\\ &\vdots\\ x&\equiv a_n\pmod{m_n} \end{aligned} \right. \end{equation} \]

给出的通解形式为:

\[x=\sum_{i=1}^na_it_iM_i\%M \]

其中 \(M=\prod\limits_{i=1}^nm_i,M_I=\frac M{m_i},M_it_i\equiv1\pmod {m_i}\)

不难发现当 \(M_i和m_i\) 不互质时, \(t_i\) 根本无法求得

所以这时需要扩展中国剩余定理 exCRT 出场了

(下文中均使用exCRT代指扩展中国剩余定理)

exCRT的基本思想

不同于中国剩余定理,exCRT尝试不停将两个方程合并为一个,这样直到方程只剩一个时,问题也就迎刃而解了

如何合并呢?

\[\begin{align} \notag &对于下面两个方程:\\\notag &\ x\equiv a_1\pmod {m_1}\\\notag &\ x\equiv a_2\pmod {m_2}\\\notag &有\ x=a_1+k_1m_1=a_2+k_2m_2\\\notag &即\ k_1m_1-k_2m_2=a_2-a_1\\\notag &这个方程我们很熟悉,它其实就是裴蜀等式\\\notag &那么这个方程有解(k_1,k_2)的条件就是:\\\notag &\ \gcd(m_1,m_2)|(a_2-a_1)\tag{1}\\\notag &下一步就是如何求出 k_1,k_2\\\notag &约定 d=\gcd(m_1,m_2),p_1=\frac {m_1}d,p_2=\frac {m_2}d\\\notag &\therefore k_1p_1-k_2p_2=\frac {a_2-a_1}d\\\notag &\because\ 当且仅当 d\ |\ (a_2-a_1)时方程组有解\\\notag &\therefore\ \frac{a_2-a_1}d\in\Z\\\notag &我们对下面这个方程求解(\lambda_1,\lambda_2):\\\notag &\lambda_1p_1+\lambda_2p_2=1\\\notag &\because 显然p_1,p_2互质\Rightarrow\ 方程一定有解\\\notag &\therefore\ k_1=\frac{a_2-a_1}d\lambda_1,k_2=-\frac{a_2-a_1}d\lambda_2\\\notag &有\ x=a_1+\frac{a_2-a_1}d\lambda_1m_1\\\notag &\therefore\ 上面两个方程的通解为:\\\notag &(a_1+\frac {a_2-a_1}d\lambda_1m_1)+k\times\text{lcm}(m_1,m_2),k\in\Z\\\notag \end{align} \]

为什么通解间一定间隔 \(\text{lcm}(m_1,m_2)\)

设上述方程组的解集中存在两个数 \(\text{lcm}(m_1,m_2)\ge x\ge y\ge 0\in\N\)

有:

\[\begin{equation} \left\{ \begin{aligned} x&\equiv a_1\pmod {m_1}\\ x&\equiv a_2\pmod {m_2} \end{aligned} \right. , \left\{ \begin{aligned} y&\equiv a_1\pmod m_1\\ y&\equiv a_2\pmod m_2 \end{aligned} \right. \end{equation} \]

\[\begin{equation} \Rightarrow\left\{ \begin{aligned} (x-y)\%m_1=0\\ (x-y)\%m_2=0 \end{aligned} \right. \Rightarrow \text{lcm}(m_1,m_2)\ |\ (x-y) \end{equation} \]

因为 \(x,y\le \text{lcm}(m_1,m_2)\Rightarrow x-y\le\text{lcm}(m_1,m_2)\)

所以 \(x-y=0\Rightarrow x=y\)

得证

实现

typedef long long lld;
lld n,m[maxn],a[maxn];
inline lld times(lld a,lld b,lld mo){
    lld ans=0;
    while(b){
        if(b&1)an=(an+a)%mo;
        a=(a+a)%mo;
        b>>=1;
    }
    return an%mo;
}
inline lld gcd(lld a,lld b,lld &x,lld &y){
    if(b==0){
        x=1;y=0;return a;
    }
    lld g=gcd(b,a%b,y,x);
    y=y-a/b*x;
    return g;
}

inline void sol(){
    lld ans=a[1],M=m[1],x,y;
    for(int i=2;i<=n;i++){
        lld res=((a[i]-ans)%m[i]+m[i])%m[i];
        lld g=gcd(M,m[i],x,y);
        if(res%g!=0){
            printf("%d",-1);
            return;
        }
        x=times(x,res/g,m[i]);
        ans+=x*M;
        M=m[i]/g*M;
        ans=(ans%M+M)%M;
    }
    printf("%lld",ans);
}
posted @ 2022-05-31 20:00  Locked_Fog  阅读(301)  评论(0)    收藏  举报