中国剩余定理

/*
mi之间互质
同余方程组 :
设正整数m1.m2.mk两两互素,则方程组
x ≡ a1 (mod m1)
x ≡ a2 (mod m2)
x ≡ a3 (mod m3)
.
.
x ≡ ak (mod mk)
有整数解,
解为  x ≡ (a1 * M1 * 1/M1 + a2 * M2 * 1/M2 + a3 * M3 * 1/M3 + …… +ak * Mk * 1/Mk) mod M
其中 M = M1 * M2 * M3 * …… * Mk, Mi为M/mi, 1/Mi为Mi的逆元
*/

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

LL CRT(int m[], int a[], int n)  // m 是 mod 的数, a 是余数, n 是方程组组数
{
    LL M = 1, ans = 0;
    for(int i = 0; i < n; i++)
        M *= m[i];
    for(int i = 0; i < n; i++) {
        int x, y;
        LL Mi = M / m[i];
        /*  假设 X = α1 + α2 + ... + αn
            α1 = ai*m2*m3*...*mn能被 m2~mn整除
            然后我们需要求出 ai * (M/m[i]) ≡ ai(mod m[i])
            则我们需要求出在(mod m[i])情况下 (M/m[i])^-1
            因为mi之间互质,所以M/m[i] 与 m[i]互质
            则在拓展欧几里得中求出 M/m[i] ≡ 1 (mod m[i]) 
        */
        exgcd(Mi, m[i], x, y); //求出的 x 即 Mi 的逆元
        ans = (ans + Mi * a[i] * x % M + M) % M;
    }
    return ans;
}

 

你可能感兴趣的:(中国剩余定理)