「学习笔记」中国剩余定理及扩展

版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/81843440

中国剩余定理总是不太熟练,写一篇 B l o g 复习一下好了。

中国剩余定理

n 个线性同余方程: x a i ( m o d m i ) m i 都互质,求解这个线性同余方程组

使用中国剩余定理( C h i n e s e r e m a i n d e r t h e o r e m c r t )来解决,它是一种构造方法,本质思想是每项只对自己有贡献.

M = i = 1 n m i ,答案为:

x = ( i = 1 n a i × M i × N i ) m o d M

其中 M i 表示 M m i N i 表示 M i m o d m i 意义下的逆元.

大概写起来是这样的,比较简单

int Crt(int n, int * m, int * a) {
    int ans = 0, M = 1;
    for(int i = 1; i <= n; i ++) M *= m[i];
    for(int i = 1; i <= n; i ++) {
        int Mi = M / m[i];
        int Ni = inv(Mi, m[i]); 
        (ans += Mi * Ni % M * a[i] % M) %= M;
    }
    return (ans + M) % M;
}

扩展中国剩余定理

n 个线性同余方程: x a i ( m o d m i ) 不保证 m i 都互质,求解这个线性同余方程组

使用扩展中国剩余定理 E x t e n d e d C h i n e s e R e m a i n d e r T h e o r e m c r t )解决, S c α p e 鸽鸽 称其为增量法.

考虑每次如何把两个线性同余方程合并。
假设有两个方程, x a ( m o d b ) x c ( m o d d )

由于第一个式子得: x = b t + a .
于是得到: b t + a c ( m o d d )
b t c a ( m o d d )
然后这是经典的同余方程,直接使用 e x g c d 求解.

解出: t t 0 ( m o d d g c d ( b , d ) )
于是得到 x = b t + a ( m o d d g c d ( b , d ) )

于是每次我们两两合并,合并 n 1 次,就完事了.

LL exgcd(LL a, LL b, LL &x, LL &y, LL &g) {
    if(!b) x = 1, y = 0, g = a;
    else exgcd(b, a % b, y, x, g), y -= x * (a / b);
}

LL excrt(int n, LL * m, LL * a) { //x = a[i] (mod m[i])
    LL c = a[1], d = m[1], p, q, g;
    for(int i = 2; i <= n; i ++) {
        exgcd(d, m[i], p, q, g);
        LL tmp = a[i] - c;
        if(tmp % g != 0) return ; //No result
        p *= tmp / g;
        p = (p % (m[i] / g) + (m[i] / g)) % (m[i] / g);
        c += p * d;
        d = d / g * m[i];
        c %= d;
    }
    return (c % d + d) % d;
}

猜你喜欢

转载自blog.csdn.net/Binary_Heap/article/details/81843440