第二十九章 数论——中国剩余定理与线性同余方程组

news2025/2/28 17:39:07

第二十九章 数论——中国剩余定理与线性同余方程组

  • 一、中国剩余定理
    • 1、作用:
    • 2、内容:
    • 3、证明:
      • (1)逆元的存在性
      • (2)验证定理的正确性
    • 4、代码实现:
      • (1)步骤:
      • (2)问题:
      • (3)代码:

一、中国剩余定理

1、作用:

我们上一章节中,详细地讲解了如何利用扩展欧几里德算法解一个线性同余方程,但是如果我们遇到了线性同余方程组的话,我们就需要用到今天所讲解的中国剩余定理。

但是中国剩余定理的成立前提是,方程组中的模数两两互质。

2、内容:

对于方程组:

{ x ≡ a 1 ( m o d   m 1 ) x ≡ a 2 ( m o d   m 2 ) x ≡ a 3 ( m o d   m 3 ) . . . x ≡ a n ( m o d   m n ) \begin{cases} x\equiv a_1(mod\ m_1)\\ x \equiv a_2(mod \ m_2)\\ x \equiv a_3(mod\ m_3)\\ ...\\ x \equiv a_n(mod\ m_n) \end{cases} xa1(mod m1)xa2(mod m2)xa3(mod m3)...xan(mod mn)
最终的结果

x = ∑ k = 1 n a k c k c k − 1 x=\sum_{k=1}^{n}a_kc_kc_k^{-1} x=k=1nakckck1

其中:

M = ∏ k = 1 n m k M=\prod_{k=1}^{n}m_k M=k=1nmk
c k = M m k c_k=\frac{M}{m_k} ck=mkM
c k − 1 c_k^{-1} ck1是模数为 m k m_k mk的时候, c k c_k ck的逆元。

3、证明:

(1)逆元的存在性

我们先证明一下,逆元 c k − 1 c_k^{-1} ck1是存在的。

因为 m m m之间是互质的,而 c k c_k ck中不含有 m k m_k mk。因此, g c d ( c k , m k ) = 1 gcd(c_k,m_k)=1 gcd(ck,mk)=1

裴蜀定理可知:

存在 x c k + y m k = 1 xc_k+ym_k=1 xck+ymk=1

即: x c k = − y m k + 1 xc_k=-ym_k+1 xck=ymk+1

即: x c k ≡ 1 ( m o d   m k ) xc_k\equiv1(mod\ m_k) xck1(mod mk)

此时的 x x x就是逆元 c k − 1 c_k^{-1} ck1,所以逆元必定是存在的。

(2)验证定理的正确性

假设一个 c i c_i ci

i   = = k i \ ==k i ==k的时候,

c i ∗ c i − 1 ≡ 1 m o d ( m k ) c_i*c_i^{-1}\equiv 1 mod(m_k) cici11mod(mk)

两侧同时乘 a i a_i ai

a i c i ∗ c i − 1 ≡ a i   m o d ( m k ) a_ic_i*c_i^{-1}\equiv a_i\ mod(m_k) aicici1ai mod(mk)

i   ! = k i \ !=k i !=k的时候,

此时的 c i c_i ci当中是存在 m k m_k mk的,不存在的是 m i m_i mi

由于 c i c_i ci包含了 m k m_k mk,所以此时 c i ∣ m k c_i|m_k cimk

c i % m k = 0 c_i\%m_k=0 ci%mk=0

两边同时乘以 a i c i − 1 a_ic_i^{-1} aici1还是 0 0 0

因此,综合上述两种情况:
我们的 x % m k = 0 + 0 + . . . + a k c k c k − 1 + 0 x\%m_k=0+0+...+a_kc_kc_k^{-1}+0 x%mk=0+0+...+akckck1+0

即:

x ≡ a k c k c k − 1 m o d ( m k ) x\equiv a_kc_kc_k^{-1}mod(m_k) xakckck1mod(mk)

因为在第一种情况下,我们得到了:

a k c k ∗ c k − 1 ≡ a k   m o d ( m k ) a_kc_k*c_k^{-1}\equiv a_k\ mod(m_k) akckck1ak mod(mk)

所以:

x ≡ a k m o d ( m k ) x\equiv a_kmod(m_k) xakmod(mk)

符合我们的方程组。因此这个结论是正确的。

4、代码实现:

(1)步骤:

第一步:计算 M M M

第二步:计算 c i c_i ci

第三步:计算 c i − 1 c_i^{-1} ci1(利用扩展欧几里德算法)

这里讲解一下如何计算逆元 c i − 1 c_i^{-1} ci1

c i ∗ c i − 1 ≡ 1 ( m o d   m i ) c_i*c_i^{-1}\equiv 1(mod\ m_i) cici11(mod mi)

即:

c i c i − 1 + y m i = 1 c_ic_i^{-1}+ym_i=1 cici1+ymi=1

这个式子中,我们不知道的未知数有两个,一个是 c i − 1 c_i^{-1} ci1,另一个是 y y y

但我们知道的是: c i , m i c_i,m_i ci,mi

所以我们可以用扩展欧几里德算法+裴蜀定理

计算出 x ∗ c i + y ∗ m i = g c d ( c i , m i ) x*c_i+y*m_i=gcd(c_i,m_i) xci+ymi=gcd(ci,mi)

g c d ( c i , m i ) = 1 gcd(c_i,m_i)=1 gcd(ci,mi)=1

所以,我们用这两个式子求的就是,我们的目标变量
c i − 1 c_i^{-1} ci1 y y y

也就是说,我们的 x = c i − 1 x=c_i^{-1} x=ci1

第四步:套用中国剩余定理

(2)问题:

洛谷:中国剩余定理模板题
在这里插入图片描述

(3)代码:

#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int n;
LL m[N],a[N];
//扩展欧几里德算法
LL exgcd(LL a,LL b,LL&x,LL&y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    else
    {
        LL res=exgcd(b,a%b,x,y);
        LL tmp=y;
        y=x-a/b*y;
        x=tmp;
        return res;
    }
}
//中国剩余定理
LL CRT(LL m[],LL a[])
{
    LL M=1,ans=0;
    //计算M
    for(int i=1;i<=n;i++)M*=m[i];
    for(int i=1;i<=n;i++)
    {
    	//得到ci
        LL c=M/m[i],x,y;
        //计算逆元
        exgcd(c,m[i],x,y);
        //利用中国剩余定理公式
        ans=(ans%M+a[i]*c*x%M)%M;
    }
    //返回答案
    return (ans%M+M)%M;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&m[i],&a[i]);
    }
    cout<<CRT(m,a)<<endl;
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国产操作系统openEuler22.03配置yum源

作者&#xff1a;IT圈黎俊杰 本文选用的操作系统版本是openEuler22.03-LTS。openEuler是指操作系统的品牌英文名&#xff0c;中文名叫“欧拉”&#xff1b;22.03是指版本号&#xff08;openEuler以年月为版本号&#xff0c;22.03表示2022年03月发布的版本&#xff09;&#xff…

sonarqube——前端vue本地代码审查code review查看代码行数和注释率

目录一、环境二、操作1.启动2.中文3.使用三、过程踩坑1.sonarqube启动闪退2.解析报错 node 14.17一、环境 windows 64位 环境压缩包下载&#xff08;sonar9.8&#xff0c;jdk11&#xff0c;sonar-scanner&#xff09; 下载完成解压后&#xff0c;将 sonar-scanner-4.7.0.2747-…

curl 指令

勿以恶小而为之&#xff0c;勿以善小而不为---- 刘备 curl 是常用的命令行工具&#xff0c;用来请求 Web 服务器。 它的名字就是客户端&#xff08;client&#xff09;的 URL 工具的意思。 它的功能非常强大&#xff0c;命令行参数多达几十种 我们后端开发者&#xff0c; 可以…

MyISAM索引解析、InnoDB索引解析

我们经常说到的存储引擎是说数据库级别还是说表级别&#xff1f; 答&#xff1a;表级别。&#xff08;数据库级别也可以设置&#xff0c;但是最终它的级别生效是在表级别&#xff09; 1、MylSAM存储引擎索引实现 MylSAM索引文件和数据文件是分离的&#xff08;非聚集&#xf…

大数据开发中级练习题目(python超详细)

给定长度为m的非重复数组p&#xff0c;以及从其中取n&#xff08;n<m&#xff09;个数字组成新的子数组q。现要对p进行排序&#xff0c;要求&#xff1a;q在数组的最前方&#xff0c;其余数字按从小到大的顺序依次排在后面 输入样例&#xff1a; q [3, 5, 4] p [5, 4, 3…

37. 解数独

37. 解数独 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&#xff…

SAP 财务年结操作宝典

目录 一 、后台操作篇 1.1 维护会计凭证编号范围 2.2 维护CO版本 1.3 维护利润中心版本 1.4 维护物料分类账文档的编号范围 (如 1.5 复制合并凭证编号范围(如果公司没有这个业务的) 1.6 维护发票凭证的编号范围间隔 (如果不针对年度则不用维护) 1.7 维护发票凭证的编号范…

MCU-51:单片机串口详解

目录一、计算机通信简介二、串口通信简介2.1 同步通信2.2 异步通信三、串行通信的传输方式四、串口通信硬件电路五、常见接口介绍六、串口相关寄存器详解6.1 特殊功能寄存器SCON6.2 PCON寄存器6.3 TMOD寄存器七、代码演示-单片机和电脑通信7.1 串口向电脑发送数据7.2 电脑通过串…

YOLO-V5 算法和代码解析系列(二)—— 【train.py】核心内容

文章目录调试设置整体结构代码解析ModelTrainloader分布式训练FreezeOptimizerSchedulerEMA调试设置 调试平台&#xff1a;Ubuntu&#xff0c;VSCode 调试设置&#xff0c;打开【/home/slam/kxh-1/2DDection/yolov5/.vscode/launch.json】&#xff0c;操作如下图所示&#xff…

GNN基础知识

1. 泰勒公式 背景background 有一个很复杂的方程&#xff0c;我们直接计算方程本身的值可能非常麻烦。 所以我们希望能够找到一个近似的方法来获得一个足够近似的值 本质&#xff1a; 近似&#xff0c;求一个函数的近似值 one point is 近似的方法another point is 近似的…

【Java 数据结构】-优先级队列以及Java对象的比较

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的主页&#x1f319; 专栏&#xff1a;【Java 数据结构】 分享&#xff1a;美妙人生的关键在于你能迷上什么东西。——《球状闪电》 主要内容&#xff1a;优先级队列底层的堆&#xff0c;大堆的创建&#xff0c;插入&a…

Openssl 生成自签名证书

最近在调试Ingress需要使用多份证书&#xff0c;对证书的生成和使用做了简单的整理。 不用翻垃圾桶一条过 #!/bin/sh output_dir"/opt/suops/k8s/ingress-files/certs/fanht-create-ssl/" read -p "Enter your domain [www.example.com]: " DOMAIN echo…

C++11特性-线程

并发 一个程序执行多个独立任务&#xff0c;提高性能 单核cpu是通过(任务切换)&#xff0c;即上下文切换&#xff0c;有时间开销 多核cpu(当核数>任务数)&#xff0c;硬件并发 进程 运行起来的一个可执行程序&#xff08;一段程序的运行过程&#xff09; 资源分配的最小单…

百数应用中心上新了——餐饮门店管理系统

随着智能化时代的来临&#xff0c;传统的餐饮门店管理方式逐渐暴露出缺陷。不少餐饮业的掌门人都纷纷对管理方式进行了转型&#xff0c;由传统模式转变为数字化系统的管理。然而数字化管理方式也没那么容易进行&#xff0c;想要百分百满足需求的系统耗时耗力耗钱&#xff0c;成…

不懂PO 设计模式?这篇实战文带你搞定 PO

1080442 73.1 KB 为UI页面写测试用例时&#xff08;比如web页面&#xff0c;移动端页面&#xff09;&#xff0c;测试用例会存在大量元素和操作细节。当UI变化时&#xff0c;测试用例也要跟着变化&#xff0c; PageObject 很好的解决了这个问题&#xff01; 使用UI自动化测试工…

钉钉 ANR 治理最佳实践 | 定位 ANR 不再雾里看花

作者&#xff1a;姜凡(步定) 本文为《钉钉 ANR 治理最佳实践》系列文章首篇《定位 ANR 不再雾里看花》&#xff0c;主要介绍了钉钉自研的 ANRCanary 通过监控主线程的执行情况&#xff0c;为定位 ANR 问题提供更加丰富的信息。 后续将在第二篇文章中讲述钉钉基于分析算法得出 …

【TuyaOS开发之旅】BK7231N GPIO的简单使用

接口讲解 GPIO初始化 /*** brief gpio 初始化* * param[in] pin_id: 需要初始化的GPIO编号&#xff0c; 对应TUYA_GPIO_NUM_E枚举* param[in] cfg: gpio 配置** return OPRT_OK on success. Others on error, please refer to tuya_error_code.h*/ OPERATE_RET tkl_gpio_ini…

基于SpringBoot工程开发Docker化微服务

目录 1. 微服务容器化治理的优缺点 1.1 微服务容器化的优点 1.2 微服务容器化的缺点 2. 微服务的两种模式 2.1 Microservice SDK 2.2 ServiceMesh 3. 微服务容器化治理的推荐模式 4.Windows下开发容器化微服务&#xff08;非K8S&#xff09; 4.1 开发环境 4.2 代码框架…

全网最新、最详细的使用burpsuite验证码识别绕过爆破教程(2023最新)

1、前沿 最近一直在研究绕过验证码进行爆破的方法&#xff0c;在这里对自己这段时间以来的收获进行一下分享。在这里要分享的绕过验证码爆破的方法一共有2个&#xff0c;分为免费版本&#xff08;如果验证码比较奇怪可能会有识别错误的情况&#xff09;和付费版本&#xff08;…

【Qt】QtCreator远程部署、调试程序

1、添加远程设备 1)QtCreator 工具–> 选项 --> 设备 --> 添加 2)设备设置向导选择–> Generic Linux Device --> 开启向导 3)填写“标识配置的名称”(随便写)、设备IP、用户名 --> 下一步 4)选择配对秘密文件,第一次配对,可以不填写,点击“下一…