扩展中国剩余定理

扩展中国剩余定理

问题

对于同余方程组\(x \equiv a_i(mod \ m_i)\),其中\(m_i\)为不一定两两互质的整数,求x的最小非负整数解。

求解

假设已经求出前k-1个方程组成的同余方程组的一个解为x,且M是\(m_1\)~\(m_{k-1}\)的最小公倍数。则前k-1个方程的方程组通解为\(x+iM(i∈Z)\)。那么对于加入第k个方程后的方程组,我们就是要求一个正整数t,使得\(x+tM \equiv a_k(mod \ m_k)\)。转化一下上述式子得\(tM \equiv a_k-x(mod \ m_k)\)。对于这个式子我们已经可以通过扩展欧几里得求解t。若该同余式无解,则整个方程组无解;若有,则前k个同余式组成的方程组的一个解为\(x_k=x+tM\)。

所以整个算法的思路就是求解k次扩展欧几里得。

//扩展欧几里得
void ex_gcd(ll a, ll b, ll& d, ll& x, ll& y) {
    if (!b) {
        d = a, x = 1, y = 0;
    }
    else {
        ex_gcd(b, a % b, d, y, x);
        y -= x * (a / b);
    }
}

//扩展中国剩余定理(非互质) x%a[i]=r[i]
//注意这里的符号含义和上面文字部分不同
ll Chinaa(int len, ll* a, ll* r) {
    ll M = a[0], R = r[0], x, y, d;
    for (int i = 1; i < len; i++) {
        ex_gcd(M, a[i], d, x, y);
        if ((R - r[i]) % d != 0) return -1;
        x = (R - r[i]) / d * x % a[i];
        R -= x * M;
        M = M / d * a[i];
        R %= M;
    }
    return (R % M + M) % M;
}
上一篇:程序人生 | Linux Daemon 程序设计示例


下一篇:xuexi