• 同余方程和中国剩余定理


    今天做题的时候化简式子,化简到一半发现几乎就是中国剩余定理的板题,然后发现蒟蒻我不会写中国剩余定理,然后就来补习了23333333

    解线性模方程

    解法

    ( ax equiv b mod q ) 可以转化为( ax + kq = b ) 。

    当( gcd(a,q)|b ) 时,方程有解,否则无解。

    当( a ) 和( q ) 不互质时,令方程两边同时处以( gcd(a,q) ) ,得到:

    ( dfrac{a}{gcd(a,q)}x+kdfrac{q}{gcd(a,q)}=dfrac{b}{gcd(a,q)} )

    也就是:

    ( dfrac{ax}{gcd(a,q)} equiv dfrac{b}{gcd(a,q)} mod dfrac{q}{gcd(a,q)} )

    令( a_1=dfrac{a}{gcd(a,q)},b_1=dfrac{b}{gcd(a,q)},q_1=dfrac{q}{gcd(a,q)} ) ,于是有:

    ( a_1x equiv b_1 mod q_1 ) ,其中( a_1 ) 和( q_1 ) 互质。此时,在方程两边乘( a_1 ) 在模( q_1 ) 意义下的逆元,就可以得到:

    ( xequiv b_1cdot a_1^{-1} mod q_1 )

    所以( x=b_1cdot a_1^{-1} + kcdot q_1 ) ,其中( kin Z^+ )

    等价类

    对于上式( x=b_1cdot a_1^{-1} + kcdot q_1 ) ,对于任意( i,jin Z^+,i geqslant j ) ,显然,我们有:

    ( (b_1cdot a_1^{-1}+icdot q_1)-(b_1cdot a_1^{-1} + jcdot q_1)= (i-j)q_1 )

    如果( (b_1cdot a_1^{-1}+icdot q_1) ) 和( (b_1cdot a_1^{-1} + jcdot q_1) ) 同余,那么( (i-j)q_1 ) 是( q ) 的倍数。因此,( (i-j) ) 必须是( gcd(a,q) ) 的倍数。

    换句话说,在模( q ) 的剩余系下,( ax equiv b mod q ) 恰好有( gcd(a,q) ) 个解。令( t = b_1cdot a_1^{-1} ) ,则这( gcd(a,q) ) 个解分别是:( t, t+p_1 , t + 2p_1, cdots , t + (gcd(a,q)-1)p_1 ) 。

    这里稍作解释:为什么说,在模( q ) 的剩余系下,只有这( gcd(a,q) ) 个解呢?

    考虑( x_1=t ) 和( x_2=t+gcd(a,q)p_1 ) ,由上面的定义可知:( gcd(a,q)p_1=p ) 。所以,( ax_1 mod p ) 和( ax_2 mod p ) 在任何意义下都是完全一致的。同理可得其他( x=t + kp_1 ) 的情况。所以,只保留这( gcd(a,q) ) 个解就能涵盖所有的情况。

    解同余方程组(中国剩余定理)

    变量还是一个,但是变成了如下的方程组:

    egin{cases} x equiv a_1 mod m_1 cr xequiv a_2 mod m_2 cr cdots cr xequiv a_n mod m_n end{cases}

    假设此时所有的( m_i ) 两两互质。令( M=prodlimits_{i=1}^{n}m_i,w_i=dfrac{M}{m_i} ) (( w_i ) 就是除了( m_i ) 以外其他( m ) 的乘积),那么有( gcd(w_i, m_i)=1 ) (( w_i ) 和( m_i ) 互质)。

    所以,我们很容易求出( w_i ) 在模( m_i ) 意义下的逆元:

    ( t_iw_i + ym_i = 1 ) ,拓展欧几里得算法可以求出( t_i ) 。

    所以,显然有( t_iw_i equiv 1 mod m_i ) (( t_i ) 是( w_i ) 的逆元)。

    也就是:

    ( t_iw_i = km_i + 1, kin Z ) ,等价于

    ( t_iw_i + km_i = 1, k in Z )

    两边同时乘( a_i ) ,得:

    ( t_ia_iw_i + ka_im_i = a_i )

    我们知道,( k ) 表示的是模( m_i ) 的次数,所以我们可以把( ka_i ) 看作( k ) 。

    于是我们得到:

    ( t_ia_iw_i + km_i = a_i )

    又因为我们有:( x equiv a_i mod m_i ) (看题干),也就是:

    ( x = a_i + km_i )
    ( x + km_i = a_i )

    所以,我们得到如下方程组:

    ( egin{cases} t_ia_iw_i + km_i = a_i cr x + km_i = a_i end{cases} )

    注意这里两个( k ) 不一定相等,但是因为我们要保证的是( x ) 对( m_i ) 取模的结果是( a_i ) ,所以整数( k ) 对结果并没有影响(因为它们的乘数是( m_i ) )。所以我们得到:( x=t_ia_iw_i ) 。

    由定义可知,对于任意( j eq i ) ,恒有( m_j | w_i ) 。

    所以,由取模的性质,对于任意的整数( j ) 有:

    ( egin{align} & sumlimits_{i=1}^{n}t_ia_iw_i mod m_j cr = &left( t_ja_jw_j + sumlimits_{i=1}^{j-1}t_ia_iw_i + sumlimits_{i=j+1}^{n}t_ia_iw_i ight) mod m_j cr = & t_ja_jw_j mod m_j + sumlimits_{i=1}^{j-1}t_ia_iw_i mod w_j+ sumlimits_{i=j+1}^{n}t_ia_iw_i mod w_j cr = &t_ja_jw_j mod m_j cr = & a_jend{align} )

    (因为( m_j | w_i ) ,所以( sumlimits_{i=1}^{j-1}t_ia_iw_i mod w_j = 0 ) ,( sumlimits_{i=j+1}^{n}t_ia_iw_i mod m_j = 0 ) )

    所以,( x ) 的一组解就是( sumlimits_{i=1}^{n}t_ia_iw_i ) ,其中( t_i ) 是( w_i ) 关于模( m_i ) 的逆元。

    在模( M ) 的剩余系下,方程组就有唯一一组解:( sumlimits_{i=1}^{n}t_ia_iw_i mod M ) 。

    代码如下:

    // 测试代码

    #include <cstdio>
    typedef long long ll;
    
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (b == 0) {
    		x = 1;
    		y = 0; 
    		return a;
    	}
    	ll r = exgcd(b, a % b, x, y);
    	ll t = x;
    	x = y;
    	y = t - a / b * y;
    	return r;
    }
    
    // n个方程:x = a[i] % m[i], (0 <= i < n)
    ll CRT(int n, int *a, int *m) {
        ll M = 1, t, y, x = 0;
        for (int i = 0; i < n; i++) M *= m[i];
        for (int i = 0; i < n; i++) {
            ll w = M / m[i];
            exgcd(w, m[i], t, y);
    		x = ((x + t * w * a[i]) % M + M) % M;
        }
        return x;
    }
    
    int a[1000], m[1000];
    
    int main() {
    	int n;
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    		scanf("%d", a + i);
    	for (int i = 0; i < n; i++)
    		scanf("%d", m + i);
    	printf("%lld
    ", CRT(n, a, m));
    	return 0;
    }
    

    参考资料:

    中国剩余定理证明

    刘汝佳《算法竞赛入门经典——训练指南》


    本文迁移自作者原博客:icysky's Blog
    本文作者:icysky
    原文链接:同余方程和中国剩余定理
    版权声明:本博客所有文章除特别声明外,均采用CC-BY-NC-SA 4.0许可协议。icysky's Blog 版权所有,转载请注明出处。

  • 相关阅读:
    烂泥:mysql修改本地主机连接
    烂泥:ESXI开启SNMP服务
    烂泥:【解决】VMware Workstation中安装ESXI5.0双网卡问题
    JS-日历签到
    CSS-文本(中,英)
    js-无缝向上滚动
    js-键盘回车搜索enter
    小程序-初次进入小程序的授权问题(授权更新后的完整步骤)button主动授权
    字蛛(font-spider)-单独压缩字体(解决页面少有的特殊字体的字体包引用)
    js-利用插件qrcode.min.js,前端实时生成二维码
  • 原文地址:https://www.cnblogs.com/icysky/p/12885429.html
Copyright © 2020-2023  润新知