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

同余

1.线性同余方程

给定整数\(a,b,m\)求一个整数\(x\)满足\(ax \equiv b \pmod m\),或给出无解。

\(a \times x = b + my\),则\(ax + my = b\),有解的充要条件是\(gcd(a,m)|b\).

接下来只要用exgcd求出一个解,然后就可以求通解了。

2.中国剩余定理

\(m_1,m_2,m_3,……,m_n\)是两两互质的整数,对于任意的\(n\)个整数\(a_1,a_2,……,a_n\),关于\(x\)的方程组 \[ \begin{cases} x \equiv a_1 \pmod {m_1}\\x \equiv a_2 \pmod {m_2}\\……\\x \equiv a_n \pmod{m_n}\end{cases} \] 有整数解。

证明:

\(m = \prod_{i = 1}^nm_i,M_i = m / m_i\)\(t_i\)是线性同余方程\(M_it_i \equiv 1 \pmod{m_i}\)的一个解。

\(x_0 = \sum_{i = 1}^n a_iM_it_i\)是一个解

因为\(M_i\)是除了\(m_i\)以外所有数的倍数,所以\(\forall k \neq i,a_iM_it_i \equiv 0 \pmod{m_k}\)。而因为\(M_it_i \equiv 1 \pmod {m_i}\),所以 $a_iM_it_i a_i $。

这是一个特解。通解为\(x = x_0 + km(k \in Z)\)

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include<iostream>
    #include<cstdio>

    #define int long long

    using namespace std;

    int n,m[30],a[30],M = 1,v[30],t[30],V1,V2;

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

    signed main() {
    scanf("%d",&n);
    for (int i=1; i<=n; i++) {
    scanf("%d %d",&m[i],&a[i]);
    M = M * m[i];
    }
    for (int i=1; i<=n; i++)
    v[i] = M / m[i];
    for (int i=1; i<=n; i++) {
    int x0,y0;
    int gcd = exgcd(v[i],m[i],x0,y0);
    x0 %= m[i];
    if (x0 <= 0)
    x0 += m[i];
    t[i] = x0;
    }
    int sum = 0;
    for (int i=1; i<=n; i++)
    sum += a[i] * v[i] * t[i];
    sum %= M;
    if (sum < 0)
    sum += M;
    printf("%lld\n",sum);
    return 0;
    }

3.中国剩余定理的扩展版本

上面的方法要求\(m_1,m_2,……,m_n\)两两互质。现在给出一种对\(m_i\)没有要求的算法。

数学归纳法:假设前\(k - 1\)个方程已经求出了一个解\(x\)。记\(m = lcm(m_1,m_2,……,m_{k - 1})\),则\(x + i \times m (i \in Z)\)是前\(k - 1\)个方程的通解。

考虑第\(k\)个方程,求一个\(t\),使得\(x + t \times m \equiv a_k \pmod {m_k}\)。将这个方程变换一下,得到\(m \times t \equiv a_{k} - x \pmod {m_k}\),求\(t\). \[ m \times t + m_{k} \times p = a_{k} - x \]