首页 > 其他分享 >线性同余方程组

线性同余方程组

时间:2024-07-22 20:11:41浏览次数:10  
标签:方程组 pmod bmod long 模数 线性 同余 operatorname equiv

线性同余方程组

基本问题是求解形如下面的 线性同余方程组

\[\begin {aligned} \begin {cases} x \equiv a_1 \pmod {p_1} \\ x \equiv a_2 \pmod {p_2} \\ ... \\ x \equiv a_n \pmod {p_n} \end {cases} \end {aligned} \]

在 \(\operatorname {OI}\) 中有 广泛的应用

建议阅读 基本概念同余关系 章节,了解基本概念与先要知识


此处获取本节调试数据 / 代码包

全文 绝大多数 内容是对 [0] 中讲述的 粗略抄写胡乱加工


1. 中国剩余定理

即 \(CRT\),全称 \(Chinese ~ Remainder ~ Theorem\),用于求解 模数两两互质线性同余方程组

即需要保证对于任意 \(i, j \in [1, n]\),\(p_i \perp p_j\)(无需保证 \(p \in \mathbb P\))


这十分的 小学奥数,当时就有一类知名的问题

韩信点兵

今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?

—— 《孙子算经》

\(x \equiv 2 \pmod 3, x \equiv 3 \pmod 5, x \equiv 2 \pmod 7, x_{\min} ?\)

这东西 很典,但是当时的做法可能 千奇百怪,并不具有 普适性

可能换一个 模数 / 余数 / 条件数量 就寄了

中国剩余定理 就很牛!它可以 程式化的 解决一切 模数两两互质 情况下的此类问题

形式化的流程

此处 要解决的问题 是 最开始给出的 一般线性同余方程组,保证 模数两两互质

  1. 找到 \(N = \prod \limits _ {i = 1} ^ {n} p_i\),同时令 \(N_i = \dfrac N {n_i}\)

  2. 于是我们就可以把 多个式子 变成如下 一个式子,也就是得到了 通解

    \[x \equiv \sum \limits _ {i = 1} ^ {n} { a_i N_i N_i ^ {-1} } \pmod N \]

乍一看感觉这东西 很怪,于是我们来仔细解释一下 这个式子的含义

显然,\(N\) 是 所有模数的 \(\operatorname {lcm}\)(保证 模数两两互质

故 \(N _ i\) 即是 除了 \(p_i\) 以外模数的 \(\operatorname {lcm}\),显然,包含 \(N_i\) 这个因式的数被除 \(p_i\) 外 所有模数整除

换言之,\(a_i N_i N_i ^ {-1}\) 这一项 不会 对其他任何模数产生 余数上的影响

也就是说,和式 中 某一项 只对原方程组中某一个方程有贡献,任意两项间 贡献独立

这就解释了为什么我们可以用 加法 连接不同项,而不是 乘法 之类的运算

考虑分析 第 \(i\) 项对第 \(i\) 个方程的贡献,由于 \(N _ i N _ i ^ {-1} \equiv 1 \pmod {p_i}\)

故显然,我们乘上 \(a_i\) 即可使得其 模 \(p_i\) 的余数变为 \(a_i\),满足方程


例子

为了理解这个流程,我们回到刚刚 韩信点兵 的例子上

考虑找到 \(N = 3 \times 5 \times 7 = 105\),\(N_i = {35, 21, 15}\),\(N_i ^ {-1} = {2, 1, 1}\)

容易发现有 \(N_1 = \operatorname {lcm} (p_2, p_3) = \operatorname {lcm} (5, 7)\),\(N_2, N_3\) 同理

显然 \(N_i N_i ^ {-1} = {70, 21, 15}\),其分别满足 \(\bmod 3, \bmod 5, \bmod 7 = 1\)

同时,满足 \((\bmod 5, \bmod 7)\),\((\bmod 3, \bmod 7)\),\((\bmod 5, \bmod 7)\) 为 \(0\),不会做额外贡献

于是我们将之 分别乘上 \(a_i\),得到 \(a_i N_i N_i ^ {-1} = 140, 63, 30\),显然分别满足第 \(i\) 个式子条件

加和,得出最终结果 \(x \equiv 233 \pmod {N = 105}\),于是最小解 \(x = 23\),满足条件


上述流程不难理解,于是最后只剩代码实现了

inline long long EXGCD (const long long a, const long long b, long long &x, long long &y);

inline long long CRT (const long long * P, const long long * R, const int N) {
	long long M = 1, T = 0, A = 0, x, y;
	for (int i = 1; i <= N; ++ i) M = M * P[i];

	for (int i = 1; i <= N; ++ i) {
		T = M / P[i], EXGCD (T, P[i], x, y);
		A += ((__int128) 1 * (R[i] * T) * (x < 0 ? x + P[i] : x)) % M;
	}
	
	return A % M;
}

板子题 Luogu P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪 检验正确性

有一组新的 \(Hack\),很强,但很没意思

提示 考虑 R[i] * T 可能爆 int 但是小于 M(流程中的 N,故 中途取模 没用) 然后再乘上 x(N_i 的逆元)就可能 爆掉 long long,必须要 __int128 才行

2. 扩展中国剩余定理

即 \(exCRT\),用于求解 模数并不两两互质更加广泛的情况

其实很多 \(ex\) 都是扩展 模数不是质数 / 不互质 / ... 这样的情况


先考虑只有 两个式子 的简单情况,如果我们也能 将其合并成一个,那么 推广就容易了

\[\begin {aligned} \begin {cases} x \equiv a_1 \pmod {p_1} \\ x \equiv a_2 \pmod {p_2} \end {cases} \end {aligned} \]

即有 \(x = a_1 + k_1p_1 = a_2 + k_2p_2\),容易发现,求解 \(x\),无异于求解 \(k_1, k_2\),简单变形可得

\[k_1 p_1 - k_2 p_2 = a_2 - a_1 \]

\(\operatorname {exgcd}\) 求解即可,当 \(\gcd (p1, p2) \nmid a_2 - a_1\) 时,该方程无解,即 原方程组无解

模数不互质 时,原方程组 确实会有 无解的情况,例如 \(x \bmod 4 = 2, x \bmod 6 = 1\) 时

于是我们得到 \(x = a_1 + k_1 p_1 = a_2 + k_2 p_2\) 这样的 特解(其中 \(k_1, k_2\) 已被解出)

我们就可以 将之转化成一个新的方程

\[x \equiv a_1 + k_1 p_1 \pmod {\operatorname {lcm} (p_1, p_2)} \]

\(a_1 + k_1 p_1\) 是 一组特解,\(\operatorname {lcm} (p_1, p_2)\) 保证转化前的 两个方程 始终成立

于是 依次合并,就可以推广到 \(n\) 个方程的方程组,解决原问题

inline long long Mul (long long a, long long b, const long long MOD) {
	long long Ret = 0;
	while (b) {
		if (b & 1) Ret = (Ret + a) % MOD;
		a = (a + a) % MOD, b >>= 1;
	}
	return Ret;
}

inline long long EXCRT (const long long * P, const long long * R, const int N) {
	long long M = 1, T = 0, K = 0, S = 0, x, y, AP = P[1], AR = R[1];
	
	for (int i = 2; i <= N; ++ i) {
		T = EXGCD (AP, P[i], x, y), S = ((R[i] - AR) % P[i] + P[i]) % P[i];
		if (S % T) return -1;
		M = S / T, K = P[i] / T, x = Mul (x, M, K), y = Mul (y, M, K);
		AR = (AR + x * AP), AP = AP * K, AR = (AR % AP + AP) % AP;
	}
	
	return (AR % AP + AP) % AP;
}

需要一个 快速乘 来避免溢出,也可以使用 __int128好像更慢

为什么解只需要 \(K = \dfrac {p_2} {\gcd (p_1, p_2)}\) 而不是 \(\operatorname {lcm} (p_1, p_2)\)?

因为下面需要乘一个 \(p_1\)(\(a_1 + k_1p_1\)),故这里没必要对 \(\operatorname{lcm}\) 取模

板子 Luogu P4777 【模板】扩展中国剩余定理(EXCRT),上述实现 可能并不精细


3. 引用资料

[0] Number Theory —— H_W_Y

标签:方程组,pmod,bmod,long,模数,线性,同余,operatorname,equiv
From: https://www.cnblogs.com/FAKUMARER/p/18316754

相关文章

  • 同余关系
    同余关系在基本概念的部分中,我们已经简单了解了整除与余数而在这一个部分中,我们将更复杂的了解余数中的同余关系由于本节内容多在模意义下讨论,故文中可能会出现一些\(=,\equiv\)混用的情况,见谅此处获取本节调试数据/代码包全文绝大多数内容是对[0]中讲......
  • 深度学习——线性神经网络
    线性回归1.什么是线性回归以下是百度百科的参考线性回归就是去分析一堆自变量X与因变量Y的线性关系,是一种定量的计算线性回归的应用:比如想要预测房价与面积与房龄的关系,就可以表示为面积与房屋年龄分别与对应的元素相求和房价=W1*房屋面积+W2*房屋年龄+W3*房屋厕所数量+......
  • 数据结构与算法总结——线性表
    目录2线性表2.1线性表的定义2.2线性表的基本操作2.2顺序表2.2.1顺序表的定义2.2.2顺序表的基本操作2.3链式表2.3.1链表的定义2.3.2链表的分类2.3.3单向链表2.3.3.1结点设计2.3.3.2链表的初始化2.3.3.3数据的插入2.3.3.4数据的删除2.3.3.5销毁链......
  • 机器学习--线性模型
    线性模型分类:把多种数据进行区分回归:归纳出某种数据的分布规律线性模型(linearmodel):试图学得一个通过属性的线性组合来进行预测的函数公式如下:#x为特征值,w为权重,b为偏值线性回归##转化为公式时,需要把特征值数值化:            1.若数据有“序......
  • 基于pytorch演练线性回归模型
    引言本文的目的是在前文基于numpy演练可视化梯度下降的代码基础上,使用pytorch来实现一个功能齐全的线性回归训练模型。为什么仍然使用线性回归模型?线性回归模型简单,它能让我们聚集在pytorch是如何工作的,而不是模型内部的某个复杂结构或算法。与前面的[基于numpy的线性回......
  • 动手学深度学习(线性神经网络)
    看这一节前最好先移动至--动手学深度学习(预备知识),把基础知识打牢,使后续理解代码和原理更加容易因为这里是第三章的内容了,所以笔者的目录就从3开始咯。目录3.线性神经网络3.1线性回归3.11线性回归的基本元素3.12损失函数3.13解析解3.14随机梯度下降3.15矢量化加速3......
  • C#中的线性表
    什么是线性表线性表是最简单、最基本、最常用的数据结构。线性表是线性结构的抽象(Abstract),线性结构的特点是结构中的数据元素之间存在一对一的线性关系。这种一对一的关系指的是数据元素之间的位置关系,即:(1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个......
  • 数据结构:线性表-例题
    顺序存储结构和链式存储结构都可以进行顺序存取。[T/F]顺序存储结构可以进行顺序存取和随机存取;链式存储结构只可以进行顺序存取。散列存储结构能反应数据之间的逻辑关系。[T/F]散列存储通过散列函数映射到物理空间,不能反应数据之间的逻辑关系。链式存储设计时,结点......
  • 【吴恩达 机器学习 学习笔记】多元线性回归模型(1):矢量化及特征缩放
    文章目录多元线性回归模型矢量化用于多元线性回归的梯度下降法正态方程(只作了解即可)特征缩放回顾:线性回归模型及梯度下降的原理多元线性回归模型在前面的学习中,我们掌握了根据房屋的面积预测房屋价格的方法(单变量线性回归模型),如果我们的房屋特征增加(如增加了房间......
  • 山东大学数据结构与算法实验8散列表(线性开型寻址/链表散列)
    A : 线性开型寻址题目描述要求使用线性开型寻址实现描述给定散列函数的除数D和操作数m,输出每次操作后的状态。有以下三种操作:插入x,若散列表已存在x,输出“Existed”,否则插入x到散列表中,输出所在的下标。查询x,若散列表不含有x,输出“-1”,否则输出x对应下标。......