数论——中国剩余定理、扩展中国剩余定理 学习笔记

这篇具有很好参考价值的文章主要介绍了数论——中国剩余定理、扩展中国剩余定理 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

数论——中国剩余定理、扩展中国剩余定理

中国剩余定理

定义

中国剩余定理(Chinese Remainder Theorem,CRT)

求解如下形式的一元线性同余方程组(其中 \(m\) 两两互质):

$\left\{\begin{matrix} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \\ \dots \\ x \equiv a_k \pmod {m_k} \end{matrix}\right.$

过程

  1. 计算所有模数的积 \(M = \prod m_i\)
  2. 对于第 \(i\) 个方程:
    1. 计算:\(M_i = \dfrac{M}{m_i}\)
    2. 计算:\(v_i = {M_i}^{-1} \pmod{m_i}\)(乘法逆元);
    3. 计算:\(c_i = M_iv_i\)
  3. 方程组在 \(0 \sim M - 1\) 范围内的唯一解为:\(x = \sum\limits_{i = 1}^k a_ic_i \pmod M\)

证明

证明对于任意 \(i \in [1, k]\),有 \(x\equiv a_i \pmod {m_i}\)

\(i\neq j\) 时,\(M_j\) 中乘进去了 \(m_i\),所以有 \(M_j \equiv 0 \pmod {m_i}\)
所以 \(c_j \equiv M_j \equiv 0 \pmod {m_i}\)

又有 \(c_i \equiv M_i \cdot {M_i}^{-1} \pmod{m_i} \equiv 1 \pmod {m_i}\),所以我们有:

\[\begin{array}{rll} x &\equiv \sum\limits_{j=1}^k a_jc_j &\pmod {m_i} \\ &\equiv a_ic_i &\pmod {m_i} \\ &\equiv a_i &\pmod {m_i} \end{array} \]

即证明了解同余方程组的算法的正确性。

性质

  1. 系数列表 \(\{a_i\}\) 与解 \(x\) 之间是一一映射关系,方程组总是有唯一解。
    证明见:https://oi-wiki.org/math/number-theory/crt/

  2. 设模 \(M\) 意义下的一个特解是 \(x_0\),则通解为:\(x = x_0 + kM\),其中 \(k \in \mathbb N\).

代码

题目:P1495 中国剩余定理

点击查看代码
const int N = 10;

ll exgcd(ll a, ll b, ll &x, ll &y, ll d = 0)
{
    if (b == 0)
        x = 1, y = 0, d = a;
    else
        d = exgcd(b, a % b, y, x), y -= a / b * x;
    return d;
}

ll inv(ll a, const ll m, ll x = 0, ll y = 0)
{
    exgcd(a, m, x, y);
    return (x % m + m) % m;
}

int a[N], m[N];

int main()
{
    int n = rr;

    ll mul = 1;
    for (int i = 1; i <= n; ++i)
        m[i] = rr, a[i] = rr, mul *= m[i];

    ll x = 0;
    for (int i = 1; i <= n; ++i)
    {
        ll t = mul / m[i], c = inv(t, m[i]);
        x = (x + a[i] * t % mul * c % mul) % mul;
    }

    printf("%lld\n", x);
    return 0;
}

应用

CRT 合并

若要求一个大数 \(r \bmod m\) 的结果 \(x\),即求解关于 \(x\) 的线性同余方程 \(x \equiv r \pmod m\)

则可以将模数分解为 \(m = \sum\limits_{i = 1}^k p_i\)(即质因数分解,\(p\) 两两互质);

然后去求解 \(x\) 在模各个 \(p_i\) 意义下的结果,最后用 CRT 合并;则求出来的答案一定是一一对应的。

即将 \(x \equiv r \pmod m\) 转换为一个线性同余方程组:\(\left\{\begin{array}{c} x \equiv r \pmod {m_1} \\ x \equiv r \pmod {m_2} \\ \dots \\ x \equiv r \pmod {m_k} \end{array}\right.\)

CRT 合并的举例

题目:P2480 古代猪文。题面略...

\(\dbinom{n}{m} \bmod 999911658\),即求 \(x \equiv \dbinom{n}{m} \pmod{999911658}\).

根据上方的描述,因为 \(999911658 = 2 \times 3 \times 4679 \times 35617\),原方程转化为:

\[\left\{\begin{align} x &\equiv \dbinom{n}{m} \pmod {2} \\ x &\equiv \dbinom{n}{m} \pmod {3} \\ x &\equiv \dbinom{n}{m} \pmod {4679} \\ x &\equiv \dbinom{n}{m} \pmod {35617} \end{align}\right.\]

使用 CRT 合并即可.

点击查看核心代码
// ...
const int N = 35620;

const ll MOD1 = 999911659;
const ll MOD2 = 999911658;

const ll m[4] = {2, 3, 4679, 35617};
const ll r[4] = {499955829, 333303886, 289138806, 877424796};	// 即 c[i]

// ...
int main()
{
    int n = rr, g = rr;
    if (g % MOD1 == 0)
        printf("0\n"), exit(0);

    // 分解质因数至 dv 数组...
    ll x = 0;
    for (int i = 0; i < 4; ++i)
    {
        MOD = m[i];

        // 预处理模 MOD 意义下的逆元...
        for (int j : dv)
            x = (x + lucas(n, j) * r[i] % MOD2) % MOD2;
    }

    ll r = qpow(g, x, MOD1);
    printf("%lld\n", r);
    return 0;
}

扩展中国剩余定理

定义

求解线性同余方程组\(\left\{\begin{matrix} x \equiv a_1 \pmod {m_1} \\ x \equiv a_2 \pmod {m_2} \\ \dots \\ x \equiv a_k \pmod {m_k} \end{matrix}\right.\)

但是模数 \(m_i\) 不一定两两互质。

此时因为 \(m_i\) 不一定与 \(m_j\) 互质,故不一定存在乘法逆元,即无法使用中国剩余定理。

做法

公式变形

先考虑前两个方程:\(x\equiv a_1 \pmod {m_1}\)\(x\equiv a_2 \pmod {m_2}\).
将它们转化为不定方程:\(x=m_1p+a_1=m_2q+a_2\)\(p, q \in \mathbb Z\).
则有 \(m_1p-m_2q=a_2-a_1\).

解的情况

由裴蜀定理:
\(\gcd(m_1,m_2) \nmid a_2-a_1\) 时,无解;
\(\gcd(m_1,m_2) \mid a_2-a_1\) 时,有解。

求解不定方程

现在考虑如何使用扩展欧几里得算法求出一组可行解:

考虑方程:\(m_1p-m_2q=a_2-a_1\).
因为 \(\gcd(m_1,m_2) \mid a_2-a_1\),所以方程两边可以同时除去 \(\gcd(m_1,m_2)\),同时设:

$\left \{ \begin{array}{rl} k_1 &= \dfrac{m_1}{\gcd(m_1,m_2)} \\\\ k_2 &= \dfrac{m_2}{\gcd(m_1,m_2)} \\\\ z &= \dfrac{a_2-a_1}{\gcd(m_1,m_2)} \end{array} \right.$

\(k_1p - k_2q = z\),且 \(k_1 \perp k_2\);所以可以用扩展欧几里得算出:

方程 \(k_1s + k_2t = 1\) 的一组解 \((s, t)\);因此有 \(\left\{\begin{array}{l} p = zs \\ q = -zs \\ \end{array}\right.\)

回看刚开始的方程 \(x\equiv a_1 \pmod {m_1}\),即可得出一个特解:

\[\begin{array}{rl} x_0 & = m_1p+a_1 \\\\ &= m_1 \cdot zs + a_1 \\\\ & = \dfrac{m_1s\times(a_2-a_1)}{\gcd(m_1,m_2)} + a_1 \end{array} \]

手模一下可知新的方程是模 \(\operatorname{lcm}(m_1, m_2)\) 意义下的。

然后再考虑将特解转为通解,这一点很简单,在此引用 rxj 的一句话:从线性代数的角度讲,这个通解的构造方式是十分平凡的。对 \(\operatorname{lcm}(m_1, m_2)\) 取模的结果,将整个整数集划分成了 \(\operatorname{lcm}(m_1, m_2)\) 个等价类,哪个等价类里面有特解,那整个等价类肯定全都是解。

也就是通解 \(x' = x_0 + k\times\operatorname{lcm}(m_1, m_2)\),其中 \(k \in \mathbb Z\).

然后就可以得出合并后的方程:\(x \equiv x' \pmod{\operatorname{lcm}(m_1, m_2)}\).

如果你没看懂,可以再看看 rxj 的 https://www.luogu.com.cn/blog/blue/kuo-zhan-zhong-guo-sheng-yu-ding-li

代码(此处的乘法比较容易溢出,一般开大一点,long long 不行就 int128):

void merge(ll &a1, ll &m1, ll a2, ll m2)
{
    ll g = gcd(m1, m2), m = m1 / g * m2;

    ll p, q;
    exgcd(m1 / g, m2 / g, p, q);

    p = p * m1 % m;
    p = p * ((a2 - a1) / g) % m;

    a1 = (a1 + p + m) % m;
    m1 = m;
}

例题

题目:P4777 扩展中国剩余定理

点击查看代码

这道题很坑,数很大,我开到了 int128...

typedef __int128_t vl;

const int N = 1e5 + 10;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll exgcd(ll a, ll b, vl &x, vl &y)
{
    if (b == 0)
    {
        x = 1, y = 0;
        return a;
    }
    ll d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

void merge(ll &a1, ll &m1, ll a2, ll m2)
{
    ll g = gcd(m1, m2), m = m1 / g * m2;

    vl p, q;
    exgcd(m1 / g, m2 / g, p, q);

    p = p * m1 % m;
    p = p * ((a2 - a1) / g) % m;

    a1 = (a1 + p + m) % m;
    m1 = m;
}

int main()
{
    int n = rr;

    ll mm = rr, aa = rr;
    for (int i = 1; i < n; ++i)
    {
        ll m = rr, a = rr;
        merge(aa, mm, a, m);
    }

    printf("%lld\n", aa % mm);
    return 0;
}

Reference

[1] https://oi-wiki.org/math/number-theory/crt/
[2] https://www.bilibili.com/video/BV1AN4y1N7Su/
[3] https://www.bilibili.com/video/BV1Ut4y1F7HG/
[4] https://numbermatics.com/n/999911658/
[5] https://www.luogu.com.cn/blog/blue/kuo-zhan-zhong-guo-sheng-yu-ding-li文章来源地址https://www.toymoban.com/news/detail-712031.html

到了这里,关于数论——中国剩余定理、扩展中国剩余定理 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法基础-数学知识-欧拉函数、快速幂、扩展欧几里德、中国剩余定理

    互质就是两个数的最大公因数只有1,体现到代码里面就是 a和b互质,则b mod a = 1 mod a (目前我不是很理解,但是可以这样理解:a和b的最大公因数是1,即1作为除数和b作为除数时,对于被除数a来说余数是一样的,即1/a的余数和b/a是一样的,即 b mod a = 1 mod a ) 欧拉函数的作用是

    2024年02月09日
    浏览(45)
  • 数论——欧拉函数、欧拉定理、费马小定理 学习笔记

    定义 欧拉函数(Euler\\\'s totient function),记为 (varphi(n)) ,表示 (1 sim n) 中与 (n) 互质的数的个数。 也可以表示为: (varphi(n) = sumlimits_{i = 1}^n [gcd(i, n) = 1]) . 例如: (varphi(1) = 1) ,即 (gcd(1, 1) = 1) ; (varphi(2) = 1) ,即 (gcd(1, 2) = 1) ; (varphi(3) = 2) ,即 (gcd(1, 3

    2024年02月08日
    浏览(43)
  • 数论——卢卡斯定理、求组合数 学习笔记

    温馨提示:组合数一般较大,下面的示范代码均无视数据范围,如果爆 int 请自行开 long long 或高精度处理。 从 (n) 个不同元素中,任取 (m) 个元素组成一个集合,叫做从 (n) 个不同元素中取出 (m) 个元素的一个组合;从 (n) 个不同元素中取出 (m leq n) 个元素的所有组合

    2024年02月08日
    浏览(40)
  • RSA的中国剩余定理(CRT)算法解密

    1.公私钥计算 (1) 计算 n = p x q ; (2) 计算Φ(n)= (p-1) x (q-1); (3) 选择 e ,且e与Φ(n)互素 ; (4) 确定d x e= 1 mod Φ(n); (5) 确定公钥 PU = {n , d}, 私钥 PR = {n,e} 2.加解密 明文M ;加密Y= M^e mod n; 解密 M = Y^d mod n; p和q是互相独立的大素数,n为p*q,对于任意(m1, m2), (0=m1

    2024年02月08日
    浏览(46)
  • RSA-CRT 使用中国剩余定理CRT对RSA算法进行解密

    使用中国剩余定理对RSA进行解密,可以提高RSA算法解密的速度。 有关数论的一些基础知识可以参考以下文章: 密码学基础知识-数论(从入门到放弃) 设p和q是不同的质数,且n = p*q。对于任意(X1, x2),其中 0 ≤ x1 p 和 0 ≤ x2 q,存在数x,其中 0 ≤ x n。 中国剩余定理给出了以下的

    2024年02月04日
    浏览(40)
  • ES9学习 -- 对象的剩余参数与扩展运算符 / 正则扩展 / Promise.finally / 异步迭代

    // kerwin {age:100,location: ‘dalian’} 其中…other 可以拿到对象的剩余参数 // {name: ‘xiaoming’,location: ‘dalian’,age: 18] 在实际开发中,我们会使用ajax() 封装一些默认的属性和属性值,以备用户忘记或未传入某些参数。 // { methods: “get”, async: true, url: “/api”} 正则表达式命名捕获

    2024年04月09日
    浏览(40)
  • 数论 --- 约数和定理公式推导、最大公约数、欧几里得算法

    和试除法判断一个数是不是质数是一个道理 从小到大枚举所有的约数,如果当前数能整除这个数的话,说明这个数就是当前数的约数 优化,与试除法判断质数是一样的 如果 d 是 n 的约数,n / d 也一定能整除 n,一个数的约数也一定是成对出现的,在枚举的时候也可以只枚举

    2023年04月08日
    浏览(86)
  • 蓝桥杯AcWing学习笔记 8-1数论的学习(上)

    我的AcWing 题目及图片来自蓝桥杯C++ AB组辅导课 蓝桥杯省赛中考的数论不是很多,这里讲几个蓝桥杯常考的知识点。 欧几里得算法代码: 就是因式分解的定理,所有的整数都可以唯一分解成若干个质因子乘积的形式: N = P 1 α 1 × P 2 α 2 × . . . × P k α k N=P_{1}^{α_{1}}×P_{2}^{α

    2024年01月16日
    浏览(81)
  • 数论——线性同余方程、乘法逆元 学习笔记

    众所周知: 如果爆 int 请自行开 long long 或边读边模,或高精度处理。 定义 若 (a bmod m = b bmod m) ,则称 (a) 与 (b) 关于模 (m) 同余,记为 (a equiv b pmod m) . 同余的性质 反身性: (a equiv a pmod m) ; 对称性:若 (a equiv b pmod m) ,则 (b equiv a pmod m) ; 传递性:若 (

    2024年02月08日
    浏览(47)
  • 欧拉定理 & 扩展欧拉定理

    观前提醒 :「文章仅供学习和参考,如有问题请在评论区提出」 目录 前置 剩余类(同余类) 完全剩余系(完系) 简化剩余系(缩系) 欧拉函数 欧拉定理 扩展欧拉定理 参考资料 给定一个正整数 (n) ,把所有的整数根据 模 (n) 的余数 (rin [0, n - 1]) 分为 (n) 类,每一类

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包