Skip to content

中国剩余定理

2021-09-02

INFO

若无特殊说明,本章涉及的变量皆为正整数。

简介

中国剩余定理最早发现于《孙子算经》中。

QUOTE

有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?

即求满足下列条件的 x

{xmod3=2xmod5=3xmod7=2

它的通解公式为 x=233+105k

《孙子算经》中只给出了最小正整数解,也就是 k=2 时的解:x=23

不过,今天我们只关心中国剩余定理更普遍的应用。

问题

中国剩余定理指关于 x 的同余方程组的解法:

{xa1 (mod m1)xa2 (mod m2)xak (mod mk)

其中 a1,a2,,ak 两两互质。

解法

M=i=1kmi

Mi=Mmi,即除 mi 外,其余所有 m 的乘积。

Miti1(modmi)tiMi 关于模 mi乘法逆元

利用以上数据可以构造一个解:

x= a1M1t1+a2M2t2+a3M3t3++akMktk= i=1kaiMiti

其正确性显然。

模板

cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 16;
LL n, a[N], m[N], M[N], prodM = 1, ansX;

void exGcd(int a, int b, int &x, int &y) {
    if (b == 0) { x = 1, y = 0; return; }
    exGcd(b, a % b, x, y);
    int t = x; x = y, y = t - a / b * y;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) {
        cin >> a[i] >> m[i];
        prodM *= m[i];
    }
    for (int i = 1; i <= n; i ++) {
        M[i] = prodM / m[i];
        LL x = 0, y = 0;
        exGcd(M[i], m[i], x, y);
        ansX += a[i] * M[i] * (x + m[i]) % m[i];
    }
    cout << ansX % prodM;
    return 0;
}