中国剩余定理(CRT)及其拓展(ExCRT)
中国剩余定理 CRT
推导
给定\(n\)个同余方程
\[\left\{
\begin{aligned}
x &\equiv a_1 \pmod{m_1} \\
x &\equiv a_2 \pmod{m_2} \\
&... \\
x &\equiv a_n \pmod{m_n}
\end{aligned}
\right.
\]\(m_1, m_2 , ... , m_n\)两两互质
令\(M = \prod_{i=1}^{n} m_i\),求\(x \mod M\)
解决该问题的方法是构造。
我们假定最终答案的形式是一个\(n\)个项的和式,对每个同余方程的构造反应在对应项的系数上。
如果要对每一个项分别构造,就要求为每一项乘上一个合适的数,使得每项构造的系数对其他方程的结果没有影响。
容易想到构造
\]
显然该数仅在模\(m_i\)时不为\(0\),于是改变该项的系数将不会对其他方程造成影响。
现在我们希望该项模\(m_i\)意义下是\(a_i\),但上一次的构造残留下了一个\(M_i\)。简单粗暴的乘上\(M_i\)在模\(m_i\)意义下的逆元\(inv_{m_i}(M_i)\),让该项在模\(m_i\)意义下变为\(1\),然后乘上\(a_i\)就构造出来了。
综上,答案为
\]
模数互质条件保证了\(M_i\)非\(0\),保证了\(inv_{m_i}(M_i)\)的存在。
实现
大部分题的所有\(m_i\)都是质数,求逆元\(QPow\)即可。
对于一般的情况,上exgcd就行。
板题:洛谷P1495 曹冲养猪
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
namespace ExGcd{
ll x,y;
ll ExGcd(ll a,ll b){
ll ans;
if(a%b==0){
x=0;y=1;ans=b;
}else{
ans=ExGcd(b,a%b);
ll x1=x,y1=y;
x=y1;y=x1-a/b*y1;
}
return ans;
}
bool SolveEqu(ll a,ll b,ll c){
ll d=ExGcd(a,b);
if(c%d!=0) return 0;
x*=c/d;y*=c/d;
x=(x%b+b)%b;
y=(c-a*x)/b;
return 1;
}
}
ll Inv(ll a,ll m){
ExGcd::SolveEqu(a,m,1);
return ExGcd::x;
}
const ll CRTN=20;
namespace CRT{
ll N;
ll m[CRTN],a[CRTN];
ll Sol(){
ll ans=0,M=1;
for(ll i=1;i<=N;i++) M*=m[i];
for(ll i=1;i<=N;i++){
ll Mi=M/m[i];
ans=(ans+Mi*Inv(Mi,m[i])*a[i])%M;
}
return ans;
}
}
int main(){
using namespace CRT;
scanf("%lld",&N);
for(ll i=1;i<=N;i++)
scanf("%lld%lld",&m[i],&a[i]);
printf("%lld",Sol());
return 0;
}
拓展中国剩余定理 ExCRT
ExCRT和CRT并没有什么关系,正如ExLucas和Lucas也没什么关系
其实从纯推理的角度来看,ExCRT可能还要好想一点(
推导
问题同CRT,但是模数是任意的,并不要求互质。
这时,我们就不能保证存在逆元了。那么如何解决该问题呢?
考虑如何合并两个方程。如果我们找到了合并的方法,就能如法炮制将\(n\)个方程依次合并起来,得到答案。
\begin{aligned}
x &\equiv a_1 \pmod{m_1} \\
x &\equiv a_2 \pmod{m_2}
\end{aligned}
\right.
\]
去掉同余,化为不定方程
\begin{aligned}
x &= m_1 y_1 + a_1 \\
x &= m_2 y_2 + a_2
\end{aligned}
\right.
\]
于是得到
\]
只要找到一组满足该式的\(y_1\)和\(y_2\),就能反算出\(x\),实现合并。
而我们得到的是一个二元一次的不定方程,可以用exgcd求解。
化为标准式
\]
解就是了。如果没有解,说明同余方程组无解。
于是最后化得的合并式为
\]
实现
唯一需要注意的地方是,本来解方程应该解\((m_1,-m_2,a_2-a_1)\),但ExGCD不好处理负数,所以把\(m_2\)改成了\(m_1\)。因为我们并不需要用到\(y_2\),所以显然是没有影响的。
板题:poj2891 Strange Way to Express Integers or 洛谷P4777 扩展中国剩余定理(EXCRT)
会被卡乘法爆ll,懒得改
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
namespace ExGcd{
ll x,y;
ll ExGcd(ll a,ll b){
ll ans;
if(a%b==0){
x=0;y=1;ans=b;
}else{
ans=ExGcd(b,a%b);
ll x1=x,y1=y;
x=y1;y=x1-a/b*y1;
}
return ans;
}
bool SolveEqu(ll a,ll b,ll c){
ll d=ExGcd(a,b);
if(c%d!=0) return 0;
x*=c/d;y*=c/d;
x=(x%b+b)%b;
y=(c-a*x)/b;
return 1;
}
}
ll Gcd(ll a,ll b){
if(a%b==0) return b;
return Gcd(b,a%b);
}
namespace ExCRT{
ll a1,m1;
void Init(){
a1=0;m1=1;
}
void Expand(ll a2,ll m2){
ExGcd::SolveEqu(m1,m2,a2-a1);
ll y1=ExGcd::x;
ll mn=m1*m2/Gcd(m1,m2);
a1=(m1*y1+a1)%mn;
m1=mn;
}
}
int main(){
ll N;scanf("%lld",&N);
ExCRT::Init();
for(ll i=1;i<=N;i++){
ll a,m;scanf("%lld%lld",&m,&a);
ExCRT::Expand(a,m);
}
printf("%lld",ExCRT::a1);
return 0;
}
2019/12/21
中国剩余定理(CRT)及其拓展(ExCRT)的更多相关文章
- 中国剩余定理(CRT)及其扩展(EXCRT)详解
问题背景 孙子定理是中国古代求解一次同余式方程组的方法.是数论中一个重要定理.又称中国余数定理.一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作<孙子算经>卷下第 ...
- 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结
中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...
- 中国剩余定理 CRT
中国剩余定理 CRT 正常版本CRT 要解的是一个很容易的东西 \[ \begin{aligned} x\equiv a_1(mod\ m_1)\\ x\equiv a_2(mod\ m_2)\\ . ...
- 扩展GCD 中国剩余定理(CRT) 乘法逆元模版
extend_gcd: 已知 a,b (a>=0,b>=0) 求一组解 (x,y) 使得 (x,y)满足 gcd(a,b) = ax+by 以下代码中d = gcd(a,b).顺便求出gc ...
- 学习笔记:中国剩余定理(CRT)
引入 常想起在空间里见过的一些智力题,这个题你见过吗: 一堆苹果,\(3\)个\(3\)个地取剩\(1\)个,\(5\)个\(5\)个地取剩\(1\)个,\(7\)个\(7\)个地取剩\(2\)个,苹 ...
- 拓展中国剩余定理(exCRT)摘要
清除一个误区 虽然中国剩余定理和拓展中国剩余定理只差两个字,但他俩的解法相差十万八千里,所以会不会CRT无所谓 用途 求类似$$\begin{cases}x \equiv b_{1}\pmod{a_{ ...
- 欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍
1.欧几里得算法(辗转相除法) 直接上gcd和lcm代码. int gcd(int x,int y){ ?x:gcd(y,x%y); } int lcm(int x,int y){ return x* ...
- 中国剩余定理及其拓展 CRT&EXGCD
中国剩余定理,又叫孙子定理. 作为一个梗广为流传.其实它的学名叫中国单身狗定理. 中国剩余定理 中国剩余定理是来干什么用的呢? 其实就是用来解同余方程组的.那么什么又是同余方程组呢. 顾名思义就是n个 ...
- CRT&EXCRT 中国剩余定理及其扩展
前言: 中国剩余定理又名孙子定理.因孙子二字歧义,常以段子形式广泛流传. 中国剩余定理并不是很好理解,我也理解了很多次. CRT 中国剩余定理 中国剩余定理,就是一个解同余方程组的算法. 求满足n个条 ...
随机推荐
- Golang 入门系列(十六)锁的使用场景主要涉及到哪些?读写锁为什么会比普通锁快
前面已经讲过很多Golang系列知识,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863.html, 接下来要说的 ...
- 【集训Day4 动态规划】【2018寒假集训 Day4 更新】蛙人
蛙人 (ple) 蛙人使用特殊设备潜水.设备中有一个气瓶,分两格:一格装氧气,另一格装氮气.留在水中有时间的限制,在深水中需要大量的氧气与氮气.为完成任务,蛙人必须安排好气瓶.每个气瓶可以用它的重量和 ...
- 前端开发单位em
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 关于HashMap容量的初始化,还有这么多学问。
在<HashMap中傻傻分不清楚的那些概念>文章中,我们介绍了HashMap中和容量相关的几个概念,简单介绍了一下HashMap的扩容机制. 文中我们提到,默认情况下HashMap的容量是 ...
- Maven设置http代理
背景:有时候公司处于安全因素的考虑,需要通过代理访问因特网,这种情况需要为Maven设置htpp代理 设置步骤如下: 1 首先确认自己无法访问外网公共的中央仓库(可通过ping repo1.maven ...
- Spring 框架基础(06):Mvc架构模式简介,执行流程详解
本文源码:GitHub·点这里 || GitEE·点这里 一.SpringMvc框架简介 1.Mvc设计理念 MVC是一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集 ...
- 网页采集器-UA伪装
网页采集器-UA伪装 UA伪装 请求载体身份标识的伪装: User-Agent: 请求载体身份标识,通过浏览器发起的请求,请求载体为浏览器,则该请求的User-Agent为浏览器的身份标识,如果使用爬 ...
- [开源] 基于Layui组件封装的后台模版,HG-Layui-UI通用后台管理框架V1.0版
HG框架简介 HG-Layui-UI框架,是基于layui最新版UI搭建的一套通用后台管理框架,借鉴了市面上各大主流框架风格,采用iframe标签页实现,保留了传统开发模式的简单实用性. 为快速开发减 ...
- 代码自动机(攻 ACwing 限时题)
#include<bits/stdc++.h> #include<windows.h> using namespace std; int tot=0; void an(int ...
- pod install/update速度慢或失败的解决方案实践
本文基于 https://www.cnblogs.com/dabaomo/p/9634727.html 声明 坚决拥护党的领导,本文章所用技术乃出于工作需要,敬请谅解. 正文 可以先过去快速浏览一遍再 ...