中国剩余定理

    技术2026-04-13  6

    欢迎访问个人博客

    来源

      中国剩余定理,英文为 Chinese Remainder Theorem \text{Chinese Remainder Theorem} Chinese Remainder Theorem,简称 CRT \text{CRT} CRT。最早见于《孙子算经》中:“有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?”故又称孙子定理。

    算法简介

    适用条件

      中国剩余定理可求解如下的一元线性同余方程组,其中 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,,mn 两两互质。 ( S ) : { x ≡ a 1 (   m o d   m 1 ) x ≡ a 2 (   m o d   m 2 ) ⋮ x ≡ a n (   m o d   m n ) (S):\left\{\begin{array}{c} x \equiv a_{1}\left(\bmod m_{1}\right) \\ x \equiv a_{2}\left(\bmod m_{2}\right) \\ \vdots \\ x \equiv a_{n}\left(\bmod m_{n}\right) \end{array}\right. (S):xa1(modm1)xa2(modm2)xan(modmn)

    定理

      假设整数 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots ,m_n m1,m2,,mn 两两互质,则对任意的整数 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,,an,方程组 ( S ) (S) (S) 有解。可以通过如下方式构造得到:

    M = ∏ i = 1 n m i M=\prod\limits_{i=1}^n m_i M=i=1nmi M i = M m i M_i=\frac{M}{m_i} Mi=miM。设整数 t i t_i ti 为模 m i m_i mi 意义下 M i M_i Mi 的逆元,即 M i t i ≡ 1 (   m o d   m i ) M_it_i\equiv1\quad(\bmod m_i) Miti1(modmi)。方程组 ( S ) (S) (S) 的通解为 x = k M + ∑ i = 1 n a i t i M i , k ∈ Z x=kM+\sum\limits_{i=1}^n a_it_iM_i,k\in Z x=kM+i=1naitiMi,kZ;在模 M M M 的意义下,方程组只有一个解 x = ( ∑ i = 1 n a i t i M i )   m o d   M x=\left(\sum\limits_{i=1}^n a_it_iM_i\right)\bmod M x=(i=1naitiMi)modM

    略证

      从假设可知,对任何 i ∈ { 1 , 2 , ⋯   , n } i\in\{1,2,\cdots,n\} i{1,2,,n},由于 ∀ j ∈ { 1 , 2 , ⋯   , n } , j ≠ i \forall j\in\{1,2,\cdots,n\},j\ne i j{1,2,,n},j=i,有 gcd ⁡ ( m i , m j ) = 1 \gcd(m_i,m_j)=1 gcd(mi,mj)=1,所以 gcd ⁡ ( m i , M i ) = 1 \gcd(m_i,M_i)=1 gcd(mi,Mi)=1。根据裴蜀定理,存在整数 t i t_i ti,使得 M i t i ≡ 1 (   m o d   m i ) M_it_i\equiv1\quad(\bmod m_i) Miti1(modmi)。   由于 M i t i ≡ 1 (   m o d   m i ) M_it_i\equiv1(\bmod m_i) Miti1(modmi),故 a i t i M i ≡ a i ⋅ 1 ≡ a i (   m o d   m i ) a_it_iM_i\equiv a_i\cdot1\equiv a_i(\bmod m_i) aitiMiai1ai(modmi);又 ∀ i ∈ { 1 , 2 , ⋯   , n } \forall i\in\{1,2,\cdots,n\} i{1,2,,n},且 i ≠ j i\ne j i=j a j t j M j ≡ 0 (   m o d   m i ) a_jt_jM_j\equiv0(\bmod m_i) ajtjMj0(modmi)。所以 ∑ i = 1 n a i t i M i ≡ \sum\limits_{i=1}^n a_it_iM_i\equiv i=1naitiMi a i t i M i + ∑ j = 1 i − 1 a j t j M j + ∑ j = i + 1 n a j t j M j a_it_iM_i+\sum\limits_{j=1}^{i-1}a_jt_jM_j+\sum\limits_{j=i+1}^n a_jt_jM_j aitiMi+j=1i1ajtjMj+j=i+1najtjMj ≡ \equiv a i + ∑ j = 1 i − 1 0 a_i+\sum\limits_{j=1}^{i-1}0 ai+j=1i10 ∑ j = i + 1 n 0 ≡ a i (   m o d   m i ) \sum\limits_{j=i+1}^n 0\equiv a_i\quad(\bmod m_i) j=i+1n0ai(modmi)。   以上已经证明: x = ∑ i = 1 n a i t i M i x=\sum\limits_{i=1}^n a_it_iM_i x=i=1naitiMi 是方程组的一个解。 假设方程组存在两个解 x 1 , x 2 x_1,x_2 x1,x2,那么 ∀ i ∈ \forall i\in i { 1 , 2 , ⋯   , n } \{1,2,\cdots,n\} {1,2,,n},有 x 1 − x 2 ≡ 0 (   m o d   m i ) x_1-x_2\equiv0\quad(\bmod m_i) x1x20(modmi);又 m 1 , m 2 , ⋯   , m n m_1,m_2,\cdots,m_n m1,m2,,mn 两两互质,说明 M ∣ ( x 1 − x 2 ) M\mid(x_1-x_2) M(x1x2);所以方程组 ( S ) (S) (S) 的两个解必然相差 M M M 的整数倍。由于存在一个特解 x = x= x= ∑ i = 1 n a i t i M i \sum\limits_{i=1}^n a_it_iM_i i=1naitiMi,所以方程组 ( S ) (S) (S) 的通解为 x = k M + ∑ i = 1 n a i t i M i , k ∈ Z x=kM+\sum\limits_{i=1}^n a_it_iM_i,k\in Z x=kM+i=1naitiMi,kZ。   证毕。 (定理描述和证明部分引用维基百科词条:中国剩余定理)

    洛谷P1495 【模板】中国剩余定理(CRT)/曹冲养猪 ↬ \looparrowright

    题目描述

      自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。举个例子,假如有 16 16 16 头母猪,如果建了 3 3 3 个猪圈,剩下 1 1 1 头猪就没有地方安家了。如果建造了 5 5 5 个猪圈,但是仍然有 1 1 1 头猪没有地方去,然后如果建造了 7 7 7 个猪圈,还有 2 2 2 头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?

    输入格式

      第一行包含一个整数 n n n——建立猪圈的次数,接下来 n n n 行,每行两个整数 a i a_i ai b i b_i bi, 表示建立了 a i a_i ai 个猪圈,有 b i b_i bi 头猪没有去处。你可以假定 a i a_i ai a j a_j aj 互质。

    输出格式

      输出包含一个正整数,即为曹冲至少养母猪的数目。

    输入输出样例

    输入 #1

    3 3 1 5 1 7 2

    输出 #1

    16

    说明/提示

       1 ≤ n ≤ 10 1 \leq n\le10 1n10 1 ≤ b i ≤ a i ≤ 100000 1 \leq b_i\le a_i\le100000 1biai100000 1 ≤ ∏ i = 1 n a i ≤ 1 0 18 1 \leq \prod\limits_{i=1}^n a_i \leq 10^{18} 1i=1nai1018

    分析

      由题意得一元线性同余方程组 { x ≡ b 1 (   m o d   a 1 ) x ≡ b 2 (   m o d   a 2 ) ⋮ x ≡ b n (   m o d   a n ) \left\{\begin{array}{c}x \equiv b_{1}\left(\bmod a_{1}\right) \\x \equiv b_{2}\left(\bmod a_{2}\right) \\\vdots \\x \equiv b_{n}\left(\bmod a_{n}\right)\end{array}\right. xb1(moda1)xb2(moda2)xbn(modan),题干中已经说明 a 1 , a 2 , ⋯   , a n a_1,a_2,\cdots,a_n a1,a2,,an 两两互质,因此可用中国剩余定理求解这个方程组。   设 M = ∑ i = 1 n a i M=\sum\limits_{i=1}^n a_i M=i=1nai M i = M a i M_i=\frac{M}{a_i} Mi=aiM;那么一定存在正整数 t i t_i ti 使得 M i t i ≡ 1 (   m o d   a i ) M_it_i\equiv1\quad(\bmod a_i) Miti1(modai)。   方程组的最小正整数解为 x = ( ∑ i = 1 n b i t i M i )   m o d   M x=\left(\sum\limits_{i=1}^n b_it_iM_i\right)\bmod M x=(i=1nbitiMi)modM

    代码

    #include<iostream> #include<cstdio> #define ll long long #define N 12 using namespace std; int n; ll a[N],b[N]; inline void ex_gcd(ll a,ll b,ll &x,ll &y) { if(!b) { x=1; y=0; return; } ex_gcd(b,a%b,x,y); ll temp=x; x=y; y=temp-a/b*y; } void CRT() { int i; ll mul=1; ll ans=0; for(i=1;i<=n;i++) mul=mul*a[i]; for(i=1;i<=n;i++) { ll Mi=mul/a[i]; ll x,y; //---------------------- //扩展欧几里得算法 //求Mi模a[i]意义下的逆元 ex_gcd(Mi,a[i],x,y); x=(x+a[i])%a[i]; //---------------------- ans=ans+b[i]*Mi*x; } cout<<ans%mul<<endl; } int main() { cin>>n; int i; for(i=1;i<=n;i++) scanf("%lld%lld",a+i,b+i); CRT(); return 0; }
    Processed: 0.036, SQL: 9