中国剩余定理小记

Preface

做 qbxt 原题 GCD Table 的时候忽然发现自己不会 excrt,爬去学了一下 QwQ .

CRT 一个平凡的应用是叫做 CRT 合并的东西 .

一元线性同余方程组

问题描述

解同余方程组

\[\begin{cases}x\equiv a_1\pmod{n_1}\\x\equiv a_2\pmod{n_2}\\\cdots\\x\equiv a_k\pmod{n_k}\end{cases} \]

显然 \(x\) 有无数个解,我们只要找出 \([0, \operatorname{lcm}(n_1,n_2,\cdots,n_k))\) 中的一个解(即最小自然数解)即可 .

有一个科技叫做 Garner 算法,oi wikiLOJ 上都有资料,听说老早就 wellknown 了,但是我显然不会呀 QwQ .

互素情形 - CRT

互素,也就是 \(n_1,n_2,\cdots,n_k\) 两两互素 .

虽然说是互素吧,但其实一般都是 \(n_1,n_2,\cdots,n_k\) 都是素数,毕竟出题人造一组两两互素的数也挺难的 .

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

Chinese Remainder Theoerm

对于 \(n_i\) 两两互素的一元线性同余方程组,令 \(\displaystyle n=\prod_{i=1}^kn_i\)\(m_i=\dfrac n{n_i}\),则:

\[x\equiv\sum_{i=1}^k a_im_im_i^{-1} \pmod n \]

其中 \(m_i^{-1}\)\(m_i\)\(n_i\) 意义下的逆元 .

证明:

\(R_i=m_im_i^{-1}\),我们发现:

\[\begin{cases}R_i\equiv 1\pmod{n_i}\\R_i\equiv 0\pmod{n_j}&i\neq j\end{cases} \]

因为 \(n_i\) 是两两互素的,所以这非常显然 .

于是可以轻易验证 \(\displaystyle x=\sum_{i=1}^ka_iR_i\) 满足条件,同余 \(n\) 类似 .


此时的时间复杂度就是 \(O(k\log(\sum n_i))\),后面 \(\log\) 部分是我自己 YY 的,不对请指出 .

其实这里我们可以发现要求的是 \(n_i\) 互素,所以逆元一定存在 .

那如果逆元不一定存在,CRT 就失效了,下面来探讨一下一般情况 .

非互素情形 - ExCRT

虽然叫 ExCRT,但是和 CRT 一点关系都没有 .


考虑合并两个同余方程组:

\[\begin{cases}x\equiv a_1\pmod{n_1}\\x\equiv a_2\pmod{n_2}\end{cases} \]

答案显然是 \(\bmod \operatorname{lcm}(n_1,n_2)\) 意义下的,回去看 CRT 可以发现乘积其实是 lcm 的特例 .

\(x=k_1n_1+a_1=k_2n_2+a_2\),于是移项就得到

\[k_1n_1-k_2n_2=a_2-a_1 \]

两边同时 \(\bmod n_2\)

\[k_1n_1\equiv a_2-a_1\pmod{n_2} \]

根据 \(\bmod\) 的分配律,这个可以变成

\[k_1\cdot \dfrac{n_1}{\gcd(n_1,n_2)}\equiv \dfrac{a_2-a_1}{\gcd(n_1,n_2)}\pmod{\dfrac{n_2}{\gcd(n_1,n_2)}} \]

exgcd 解出 \(k_1\),然后代回去就能求 \(x\) 了,可以证明答案是 \(\bmod \operatorname{lcm}(n_1,n_2)\) 意义下的 .

我也不知道对不对因为我也没写过

zhx 黑科技 - 大数翻倍法

其实不互素情形的关键就是合并同余方程组 .

先把任务写上,就是要合并下面这个玩意呗

\[\begin{cases}x\equiv a_1\pmod{n_1}\\x\equiv a_2\pmod{n_2}\end{cases} \]

首先答案肯定是 \(\bmod \operatorname{lcm}(n_1,n_2)\) 意义下的,问题就是要找 \(x\bmod \operatorname{lcm}(n_1,n_2)\) 是多少 .

我们考虑直接暴力,枚举所有满足第一个同余方程的 \(x\),然后一个一个判断是否满足第二个,这样就找到答案了 .

做完了?真做完了 .

然而我们可以整一个类似启发式的东西,钦定上 \(n_1>n_2\),这样能少跳几次 .

显而易见跳超过 \(n_2\) 次就一定无解,因为肯定会产生循环,于是时间复杂度就是 \(O(n_2)\) .

想想这玩意咋行啊,总复杂度不就是 \(O(\sum n_i)\) 了吗,肯定 GG 啊 .

这里就要用到神秘的 zhx 分析法了!!

首先 \(\prod n_i\) 肯定不会爆 long long,要不然出题人也做不了,不妨就令其最大值为 \(10^{18}\) 吧 .

然后出题人如果想要卡我们,肯定得用大素数,要不然跳几下就找到解了 .

此时分析 \(\sum n_i\),最大值肯定取到 \(n=2\)\(n=1\) 还合并个毛啊),此时大概就跑 \(10^9\) 次,这样就卡掉了 .

再检验一下 \(n=3\),大概是 \(3\times 10^6\) 级别,稳过 .

但是我们发现根据均值不等式,\(n\) 再大肯定答案越小,于是很大概率就卡不掉了 .

出题人不可能整一堆 \(n=2\) 吧 /hanx 出题人也不一定知道这个算法

于是这个黑科技就被证明跑得飞快了

核心代码不超过 5 行哦,这里 是一份实现 .

posted @ 2022-06-02 11:36  Jijidawang  阅读(125)  评论(0编辑  收藏  举报
😅​