热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

扩展CRT(扩展中国剩余定理)

给定\(n\)个同余模方程\[\left\{\begin{aligned}x\equiv\,&m_1(mod\quada_1)\\x\equiv\,&m_2(mod\quada_2

给定 \(n\) 个同余模方程


\[\left\{\begin{aligned}

x\equiv\, & m_1(mod\quad a_1)\\

x\equiv\, & m_2(mod\quad a_2)\\

&\vdots\\

x\equiv\, & m_n(mod\quad a_n)

\end{aligned}

\right.

\]

不保证 \(gcd(m_i,m_j)=1(i\neq j)\) ,求最小的正整数解 \(x\)


2个方程的解

因为两两之间不互质,所以不能通过ex_gcd求解

尝试将问题缩小到两个方程,再逐步推出最后的解,有


\[\left

\{

\begin{aligned}

x\equiv\,&m_1(mod\quad a_1)\\

x\equiv\,&m_2(mod\quad a_2)

\end{aligned}

\right.

\]

也就等同于 \(\exists k_1,k_2\) ,使得


\[\left

\{

\begin{aligned}

x=&\,k_1a_1+m_1\\

x=&\,k_2a_2+m_2

\end{aligned}

\right.\tag{1}

\]

即有


\[k_1a_1+m_1=k_2a_2+m_2

\]

整理可得


\[k_1a_1-k_2a_2=m_2-m_1

\]

此时可用ex_gcd求解 \(k_1,k_2\) ,有解的充要条件是: \(gcd(a1,-a2)\mid(m_2-m_1)\)

\(d=gcd(a1,-a2)\),且 \(\exists k_1^{'},k_2^{'}\) ,使得


\[k_1^{'}a_1-k_2^{'}a_2=d

\]

可以通过ex_gcd求解得出 \(k_1^{'},k_1^{'}\)的特解,设 \(t=\frac{m_2-m_1}{d}\),则


\[\left

\{

\begin{aligned}

k_1&=k_1^{'}t\\

k_2&=k_2^{'}t\\

\end{aligned}

\right.

\]

通解形式为( \(k\) 为任意整数)


\[\left

\{

\begin{aligned}

k_1&=k_1^{'}t+k\frac{-a_2}{d}\\&=k_1+k\frac{-a_2}{d}\\

k_2&=k_2^{'}t-k\frac{a_1}{d}\\&=k_2-k\frac{a_1}{d}\\

\end{aligned}

\right.

\]

再把 \(k_1\) 的通解带入到 \(x=k_1a_1+m_1\)


\[\begin{aligned}

x&=(k_1+k\frac{-a_2}{d})a_1+m_1\\

&=k_1a_1+k\frac{a_1(-a_2)}{d}+m_1\\

&=k\frac{a_1(-a_2)}{d}+k_1a_1+m_1\\

&=\underbrace{k}_{k_1}\underbrace{lcm(a_1,-a_2)}_{a_1}+\underbrace{k_1a_1+m_1}_{m_1}

\end{aligned}

\]

这样就得到了新的


\[\left

\{

\begin{aligned}

k_1&=k\quad\\

a_1&=lcm(a_1,-a_2)\\

m_1&=k_1a_1+m_1\\

\end{aligned}

\right.

\]

与一开始方程组 \((1)\) 中的表达形式相同,这样就将两个方程合并成了一个方程


\[x=k_1a_1+m_1\tag{2}

\]

此时 \(x\) 的解就是 \(m_1\) 在模 \(a_1\) 下的最小正整数解


n个方程的解

经过 \(n-1\) 轮整合,可以把 \(n\) 个方程合并成为一个方程


\[x=ka+m

\]

最终的结果就是


\[x=(m\%a+a)\%a

\]


例题

204. 表达整数的奇怪方式



  • 每一轮合并得出的方程 \((2)\)\(k_1\) 都保证是最小正整数解,这样得到新的 \(m_1\) 是最小正整数解,以防在计算过程中溢出

  • 保证最后的最小正解,模数也应当为正

#include
#include
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);
y-=a/b*x;
return d;
}
int main() {
int n;
scanf("%d",&n);
ll a1,m1;
scanf("%lld%lld",&a1,&m1);
bool flag=true;
for(int i=0;i ll a2,m2;
scanf("%lld%lld",&a2,&m2);
a2=-a2;
ll k1,k2;
ll d=exgcd(a1,a2,k1,k2);
if((m2-m1)%d) {
flag=false;
break;
}
k1=k1*((m2-m1)/d);//特解
ll temp=abs(a2/d);
k1=(k1%temp+temp)%temp;//通解中保证最小正整数解
m1=k1*a1+m1;
a1=a1/d*a2;
}
if(flag) {
if(a1<0) a1=-a1;
m1=(m1%a1+a1)%a1;//保证最后的最小正解,模数也应当为正
printf("%lld",m1);
} else puts("-1");
return 0;
}

参考



  • 算法讲堂[基础]-数论基础定理与算法

  • https://www.acwing.com/activity/content/code/content/53307/



推荐阅读
  • 包含phppdoerrorcode的词条 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 本文详细介绍了如何使用OpenSSL自建CA证书的步骤,包括准备工作、生成CA证书、生成服务器待签证书以及证书签名等过程。 ... [详细]
  • 应用链时代,详解 Avalanche 与 Cosmos 的差异 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 本文详细介绍了如何解决DNS服务器配置转发无法解析的问题,包括编辑主配置文件和重启域名服务的具体步骤。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • Visual Studio Code (VSCode) 是一款功能强大的源代码编辑器,支持多种编程语言,具备丰富的扩展生态。本文将详细介绍如何在 macOS 上安装、配置并使用 VSCode。 ... [详细]
  • 自Emacs 24.1版本起,Emacs引入了ELPA(Emacs Lisp Package Archive)作为其内置的包管理系统,用于管理和安装来自互联网的扩展插件。本文将指导您如何配置Emacs以使用MELPA这一知名且丰富的第三方插件源。 ... [详细]
  • 本文详细介绍了在天正CAD中如何调整和修改尺寸标注的方法,包括改变标注数字大小、修改文字样式、调整标注比例等实用技巧。 ... [详细]
  • 炫龙T50游戏本深度评测:值得入手吗?
    2017年初,随着英特尔第七代酷睿处理器和英伟达GTX 1050/1050 Ti新平台的推出,各大OEM厂商迅速更新了自家产品线。炫龙也不例外,推出了搭载最新硬件的T50游戏本。本文将对这款产品进行全面评测。 ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • C# 实现可浮动工具栏功能
    本文介绍如何在 C# 中实现一个可浮动的工具栏,即工具栏可以从其初始位置拖出,并且可以重新拖回原位。通过创建一个新的窗口作为工具栏的容器,并利用 .NET Framework 提供的 ToolStrip 控件,可以轻松实现这一功能。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本章介绍了TCP/IP协议族中的链路层,其主要功能是为IP模块发送和接收IP数据报。链路层还支持一些辅助性协议,如ARP。此外,本文详细探讨了不同类型的链路层技术及其应用。 ... [详细]
author-avatar
壮丁1987_536
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有