【算法学习笔记】36:中国剩余定理(Chinese Remainder Theorem)求解线性同余方程组

中国剩余定理

假定存在 m 1 . . m k m_1..m_k m1..mk两两互质,中国剩余定理旨在求解这样的线性同余方程组中的 x x x
x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) . . . x ≡ a k ( m o d m k ) x \equiv a_1~(mod~m_1) \\ x \equiv a_2~(mod~m_2) \\ ... \\ x \equiv a_k~(mod~m_k) xa1 (mod m1)xa2 (mod m2)...xak (mod mk)
定理给出的求解方式是,设:
M = ∏ i = 1 k m i M i = M m i M= \prod_{i=1}^{k}m_i \\ M_i = \frac{M}{m_i} M=i=1kmiMi=miM
易知 M i M_i Mi m i m_i mi互质。记 M i − 1 M_i^{-1} Mi1表示 M i M_i Mi m i m_i mi的逆,则定理给出的一个 x x x的解是:
x = ∑ i = 1 k a i ⋅ M i ⋅ M i − 1 x = \sum_{i=1}^{k}a_i \cdot M_i \cdot M_i^{-1} x=i=1kaiMiMi1

如何求 M i M_i Mi关于模 m i m_i mi的乘法逆元

前面学了快速幂求乘法逆元,但是要求模数是一个质数。但前面的线性同余方程组中只限制了不同的 m i m_i mi之间两两互质,并不要求 m i m_i mi是一个质数,所以可以用扩展欧几里得算法来求乘法逆元。

根据乘法逆元的定义:

若整数 b b b m m m互质,并且对于任意的整数 a a a,如果满足 b ∣ a b~|~a b  a,则存在一个整数 x x x,使得 a b ≡ a ⋅ x ( m o d m ) \frac{a}{b} \equiv a \cdot x(mod~m) baax(mod m),则称 x x x b b b的模 m m m乘法逆元,记为 b − 1 ( m o d m ) b^{-1}(mod~m) b1(mod m)

两边除以 a a a,再把 b b b乘到右边,就有:
b ⋅ x ≡ 1 ( m o d m ) b \cdot x \equiv 1~(mod~m) bx1 (mod m)

这正是一个特殊的线性同余方程,可以用扩展欧几里得算法求出 x x x

证明

只要证明中国剩余定理给出的解是满足线性同余方程组的一个合法解即可:
x = ∑ i = 1 k a i ⋅ M i ⋅ M i − 1 x = \sum_{i=1}^{k}a_i \cdot M_i \cdot M_i^{-1} x=i=1kaiMiMi1
只要对方程组中的每一条方程一个个带入校验即可。对于任意的第 i i i条方程, x x x m i m_i mi的结果必须是 a 1 a_1 a1

考虑到解中的第 i i i a i ⋅ M i ⋅ M i − 1 a_i \cdot M_i \cdot M_i^{-1} aiMiMi1 M i − 1 M_i^{-1} Mi1 M i M_i Mi m i m_i mi下的逆,因此它们的乘积 M i ⋅ M i − 1 M_i \cdot M_i^{-1} MiMi1 m i m_i mi一定余 1 1 1,进而这一项 a i ⋅ M i ⋅ M i − 1 a_i \cdot M_i \cdot M_i^{-1} aiMiMi1模上 m i m_i mi一定余 a i a_i ai

考虑到解中的第 j j j项( j ≠ i j \neq i j=i),由于 M j M_j Mj中一定包含了一个因子 m i m_i mi,所以这一项 a j ⋅ M j ⋅ M j − 1 a_j \cdot M_j \cdot M_j^{-1} ajMjMj1 m i m_i mi一定余 0 0 0

因此,所有项的加和模 m i m_i mi一定余 a i a_i ai,证毕。

例题:洛谷P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

模板题,注意中间结果可能会爆long long,所以要用__int128,由于是对 M i M_i Mi求逆,按照题目数据范围这个exgcdinv_rp的过程也要写成long long的。

#include <iostream>
#include <vector>using namespace std;typedef long long LL;LL exgcd(LL a, LL b, LL& x, LL& y) {if (!b) {x = 1, y = 0;return a;}LL d = exgcd(b, a % b, y, x);// by + (a % b)x = d// by + (a - a/b * b) * x = d// ax + by - (a/b) * b * x = d// ax + b(y - (a/b) * x) = dy -= a / b * x;return d;
}// b和m互质求b模m的逆
LL inv_rp(LL b, LL m) {// bx = 1 (% m)// bx = 1 + my// bx + my' = 1LL x, y;exgcd(b, m, x, y);return x;
}LL crt(vector<int>& a, vector<int>& m) {LL M = 1;int n = a.size();for (int i = 0; i < n; i ++ ) {M *= m[i];}__int128 res = 0;for (int i = 0; i < n; i ++ ) {LL Mi = M / m[i];res = (res + (__int128)a[i] * Mi * inv_rp(Mi, m[i])) % M;}return (res + M) % M;
}int main() {int n; cin >> n;vector<int> a(n), b(n);for (int i = 0; i < n; i ++ ) {cin >> a[i] >> b[i];}cout << crt(b, a) << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8734.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习第一道菜(二):玩转最小二乘法

机器学习第一道菜&#xff08;二&#xff09;&#xff1a;玩转最小二乘法 一、线性函数表达式1.1 函数表达式 y y y1.2 函数表达式 f θ ( x ) f_\theta(x) fθ​(x)1.3 最小误差 二、最小二乘法&#xff1a;数据拟合大师2.1 概念及其历史背景2.2 拟合优势2.3 数学表达式2.3.1 …

关于低代码技术架构的思考

我们经常会看到很多低代码系统的技术架构图&#xff0c;而且经常看不懂。是因为技术架构图没有画好&#xff0c;还是因为技术不够先进&#xff0c;有时候往往都不是。 比如下图&#xff1a; 一个开发者&#xff0c;看到的视角往往都是技术层面&#xff0c;你给用户讲React18、M…

Python嵌套循环

# coding: utf-8 print("—————————— 嵌套循环 ——————————")while 表达式1&#xff1a;while 表达式2&#xff1a;语句块2for 循环变量1 in 遍历对象1&#xff1a;for 循环变量2 in 遍历对象2&#xff1a;语句块2 print("—————————…

【MySQL — 数据库增删改查操作】深入解析MySQL的 Retrieve 检索操作

Retrieve 检索 示例 1. 构造数据 创建表结构 create table exam1(id bigint, name varchar(20) comment同学姓名, Chinesedecimal(3,1) comment 语文成绩, Math decimal(3,1) comment 数学成绩, English decimal(3,1) comment 英语成绩 ); 插入测试数据 insert into ex…

【反悔堆】力扣1642. 可以到达的最远建筑

给你一个整数数组 heights &#xff0c;表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。 你从建筑物 0 开始旅程&#xff0c;不断向后面的建筑物移动&#xff0c;期间可能会用到砖块或梯子。 当从建筑物 i 移动到建筑物 i1&#xff08;下标 从 0 开始 &#xff09;…

搭建Spring Boot开发环境

JDK&#xff08;1.8及以上版本&#xff09; Apache Maven 3.6.0 修改settings.xml 设置本地仓库位置 <localRepository>D:/repository</localRepository> 设置远程仓库镜像 <mirror><id>alimaven</id><name>aliyun maven</name&…

算法-接雨水

hello 大家好&#xff01;今天开写一个新章节&#xff0c;每一天一道算法题。让我们一起来学习算法思维吧&#xff01; function trap(height) {// 获取柱子数组的长度const n height.length;// 如果柱子数量小于等于 2&#xff0c;无法形成凹槽接雨水&#xff0c;直接返回 0i…

实现B-树

一、概述 1.历史 B树&#xff08;B-Tree&#xff09;结构是一种高效存储和查询数据的方法&#xff0c;它的历史可以追溯到1970年代早期。B树的发明人Rudolf Bayer和Edward M. McCreight分别发表了一篇论文介绍了B树。这篇论文是1972年发表于《ACM Transactions on Database S…

Fort Firewall:全方位守护网络安全

Fort Firewall是一款专为 Windows 操作系统设计的开源防火墙工具&#xff0c;旨在为用户提供全面的网络安全保护。它基于 Windows 过滤平台&#xff08;WFP&#xff09;&#xff0c;能够与系统无缝集成&#xff0c;确保高效的网络流量管理和安全防护。该软件支持实时监控网络流…

OpenCV:图像处理中的低通滤波

目录 简述 什么是低通滤波&#xff1f; 各种滤波器简介与实现 方盒滤波 均值滤波 中值滤波 高斯滤波 双边滤波 各种滤波的对比与应用场景 相关阅读 OpenCV基础&#xff1a;图像变换-CSDN博客 OpenCV&#xff1a;图像滤波、卷积与卷积核-CSDN博客 简述 低通滤波是一…

某公交管理系统简易逻辑漏洞+SQL注入挖掘

视频教程在我主页简介或专栏里 目录: 某公交管理系统挖掘 SQL注入漏洞 越权漏洞 某公交管理系统挖掘 SQL注入漏洞 前台通过给的账号密码,进去 按顺序依次点击1、2、3走一遍功能点&#xff0c;然后开启抓包点击4 当点击上图的4步骤按钮时&#xff0c;会抓到图下数据包&a…

【数据结构】_链表经典算法OJ:分割链表(力扣—中等)

目录 1. 题目描述及链接 2. 解题思路 2.1 思路1 2.2 思路2 2.3 思路3&#xff08;本题采取该解法&#xff09; 3. 题解程序 1. 题目描述及链接 题目链接&#xff1a;面试题 02.04. 分割链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个链表…

工业相机 SDK 二次开发-VC6.0 程序示例

本文主要介绍了使用工业相机SDK(Software Development Kit)开发C程序方法及过 程。在 SDK 开发包目录下&#xff0c;提供了 13 个 VC6.0 示例程序&#xff0c;其中 MFC 程序 5 个&#xff0c;分别为 BasicDemo、ReconnectDemo、SetIODemo、ForceIpDemo、MultipleCamera&#xf…

选择困难?直接生成pynput快捷键字符串

from pynput import keyboard# 文档&#xff1a;https://pynput.readthedocs.io/en/latest/keyboard.html#monitoring-the-keyboard # 博客(pynput相关源码)&#xff1a;https://blog.csdn.net/qq_39124701/article/details/145230331 # 虚拟键码(十六进制)&#xff1a;https:/…

初阶1 入门

本章重点 C的关键字命名空间C的输入输出缺省参数函数重载引用内联函数auto关键字基于范围的for循环指针的空值nullptr 1.C的关键字 c总共有63个关键字&#xff0c;其中包含c语言的32个 这些关键字不需要特意去记&#xff0c;在我们日后写代码的过程中会慢慢用到并记住。 2.…

以太网详解(六)OSI 七层模型

文章目录 OSI : Open System Interconnect&#xff08;Reference Model&#xff09;第七层&#xff1a;应用层&#xff08;Application&#xff09;第六层&#xff1a;表示层&#xff08;Presentation&#xff09;第五层&#xff1a;会话层&#xff08;Session&#xff09;第四…

【Python】 python实现我的世界(Minecraft)计算器(重制版)

【Python】 python实现我的世界(Minecraft)计算器 文章目录 【Python】 python实现我的世界(Minecraft)计算器1.引言与原理2.写代码之前的配置1.BuidTools.jar文件配置服务器2.raspberryjuice-1.12.1.jar用python控制服务器 3.第三方库mcpi的基本方法4.计算器构建的思路5.源码展…

STM32使用VScode开发

文章目录 Makefile形式创建项目新建stm项目下载stm32cubemx新建项目IED makefile保存到本地arm gcc是编译的工具链G++配置编译Cmake +vscode +MSYS2方式bilibiliMSYS2 统一环境配置mingw32-make -> makewindows环境变量Cmake CmakeListnijia 编译输出elfCMAKE_GENERATOR查询…

uni-app 程序打包 Android apk、安卓夜神模拟器调试运行

1、打包思路 云端打包方案&#xff08;每天免费次数限制5&#xff0c;最简单&#xff0c;可以先打包尝试一下你的程序打包后是否能用&#xff09;&#xff1a; HBuilderX 发行App-Android云打包 选择Android、使用云端证书、快速安心打包本地打包&#xff1a; HBuilderX …

Hugging Face 推出最小体积多模态模型,浏览器运行成为现实!

1. SmolVLM 模型家族简介 1.1 什么是 SmolVLM-256M 和 SmolVLM-500M,它们为何如此重要? 在人工智能的多模态模型领域,如何在有限的计算资源下实现强大性能一直是一个重要的挑战。SmolVLM-256M 和 SmolVLM-500M 是最近推出的两款视觉语言模型,它们不仅突破了传统“大模型”…