zoukankan      html  css  js  c++  java
  • 中国剩余定理

    中国剩余定理

    问题引入

    求出一个数,使得这个数除 (3)(2), 除 (5)(3), 除 (7)(2)

    问题求解

    下面我们依照中国剩余定理的算法流程对这个问题进行求解,并且逐步解释其原理

    对于这个问题,我们有一个比较简单的方法是:先找出每一个方程的解,再通过加其模数使之与其他方程的解的值相等

    然而这样的想法是很难进行求解的,我们引入如下两个性质:

    性质一((a + b) mod p = a mod p + b mod p)

    性质二((a * b) mod p = (a mod p) * b)

    性质一告诉我们:如果有一个数除 (5)(3),还有任意两个数被 (5) 整除,则这三个数的和满足除 (5)(3)

    那么,我们构造出三个数 (a, b, c) 分别满足这三个方程,并且能被其它两个数整除,那么(a + b + c)就是这个方程组的一个解

    因此,这个问题被我们转化成了一个简单的问题:求一个 (x),使得(x mod 3 = 0, x mod 7 = 0) 并且 (x mod 5 = 3)

    显然,x会是 (3 * 7 = 21) 的倍数,那我们直接考虑 ((k * 21) mod 5 = 3) 就行了。由性质二可以得知,我们只需将 (21 mod 5) 扩大 ((5 imes d) / (21 mod 5)) 倍就行了,这个值就是 (k) 的值

    上面这个问题(以本体为例)相等于求解一个 (x) 使得 (1 * x = 3 pmod 5) 这个问题可以通过拓展欧几里得算法求解

    以本题为例,我们写出计算过程。

    1. 求出最小公倍数(lcm = 3 * 5 * 7 = 105)
    2. 求出个数对应基础数
      对于第一个条件, 我们有(105 / 3 = 35)(35 mod 3 = 2) 满足,则基础数为 (35)
      对于第二个条件, 我们有(105 / 5 = 21)(21 mod 5 = 1) 不满足,将这个式子乘 (3),使得 (63 mod 5 = 3) 则基础数为 (63)
      对于第三个条件, 我们有(105 / 7 = 15)(15 mod 7 = 1) 不满足,与上一个步骤相同,乘 (2) 得到基础数为 (30)
      把基础数相加: (35 + 63 + 30 = 128)
    3. 减去最小公倍数(在比最小公倍数大的情况下)
      得到(x = 128 - 105 = 23)

    数学模型

    (m_1, m_2, cdots, m_n) 是两两互质的整数,(m = prod_{i = 1}^nm_i, M_i = m / m_i)(t_i) 是线性同余方程 (M_it_i = 1 pmod m_i) 的一个解,对于任意的 (n) 个数 (a_1, a_2, cdots, a_n), 方程组 $$x = a_i pmod m_i$$有整数解,解为 (x = sum_{i = 1}^na_iM_it_i)

    证明

    因为 (M_i = m / m_i) 是除 (m_i) 意外所有数的倍数,所以 (forall k ot= i, a_iM_it_i = 0 pmod m_k), 又因为 (a_iM_it_i = a_i pmod m_i) 所以带入 (x), 原方程成立

    代码

    ll exgcd(ll a, ll b, ll &x, ll &y) {
        if (b == 0) { y = 0, x = 1; return a; }
        int d = exgcd(b, a%b, y, x);
        return y = y - x * (a / b), d;
    }
    
    ll base[maxn], ans[maxn];
    ll M = 1;
    
    inline void CRT() {
        for (int i = 1; i <= n; ++ i) base[i] = M / a[i];
        ll y;
        for (int i = 1; i <= n; ++ i) {
            exgcd(base[i], a[i], ans[i], y);
            (res += ans[i] * b[i] * base[i]) %= M;
        }
        printf("%lld", (res + M) % M);
    }
    
  • 相关阅读:
    各版本mysql乱码的问题解决
    Centos+apache2.4.2+mysql5.5+php5.3.10+memcache+sphinx配置全程
    Mysql 优化
    Mysql 表优化
    Mysql 索引优化
    python整合连续数字的练习,包含itertoolsgroupby用法
    MySQL INTO OUTFILE/INFILE导出导入数据
    python lambda使用if
    mysql小知识
    Python利用urllib2抓取网页返回乱码的问题
  • 原文地址:https://www.cnblogs.com/Alessandro/p/9839521.html
Copyright © 2011-2022 走看看