一、扩展欧几里得

求解方程 \(ax+by=\gcd(a,b)\)。

int exgcd(int a,int b,int &x,int &y){
if(!b) return x=1,y=0,a;
int d=exgcd(b,a%b,x,y);
int z=x; x=y,y=z-y*(a/b);
return d;
}

对于更为一般的方程 \(ax+by=c\),设 \(d=\gcd(a,b)\)。我们可以求出 \(ax+by=d\) 的一组特解 \(x_0,y_0\)。这所以 \(\frac{c}{d}\) 也必须为整数,否则无解(所以该方程有解当且仅当 \(d\mid c\))。我们令 \(x_0,y_0\) 同时乘上 \(\frac{c}{d}\),得 \(a\frac{cx_0}{d}+b\frac{cy_0}{d}=c\)。那么 \(x=\frac{c}{d}\cdot x_0,y=\frac{c}{d}\cdot y_0\) 即为一组解。

事实上,方程 \(ax+by=c\) 的通解可以表示为:

\[x=\frac{c}{d}x_0+k\frac{b}{d},\,y=\frac{c}{d}y_0-k\frac{a}{d}\,(k\in \mathbb{Z}) \]

那么若求得一个 \(x\),则该方程 \(x\) 的最小整数解就是 (x%(b/d)+b/d)%(b/d)

二、中国剩余定理

1. 求解

考虑求解方程组 \(x\equiv r_i\pmod {m_i}\)。即:

\[\begin{cases} x\equiv r_1\pmod {m_1}\\ x\equiv r_2\pmod {m_2}\\ \ \ \ \ \vdots\\ x\equiv r_k\pmod {m_k} \end{cases} \]

其中 \(m_i\) 两两互质。中国剩余定理(CRT)的表述如下:

令 \(M=\prod_{i=1}^k m_i\),则该方程组在 \([0,M)\) 范围内有唯一解,且显然是最小整数解。设 \(M_i=\frac{M}{m_i}\),\(t_i=M_i^{-1}\) 表示 \(M_i\) 在模 \(m_i\) 意义下的逆元,即 \(M_it_i\equiv 1\pmod {m_i}\)。则最小解为:

\[x=\left(\sum_{i=1}^k r_it_iM_i\right)\mod M \]

2. 证明

\[x=\sum_{i=1}^k r_it_iM_i\equiv r_j \pmod {m_j} \]

当 \(i\neq j\) 时,\(M_i=\frac{m_1m_2\cdots m_k}{m_i}\) 必为 \(m_j\) 的倍数,则有 \(r_it_iM_i\equiv 0\pmod {m_j}\)。

否则,又因为 \(M_jt_j\equiv 1\pmod {m_i}\),所以 \(r_jt_jM_j\equiv r_j\pmod {m_j}\)。

综上,对于任意 \(i\),总有 \(x=\sum_{i=1}^k r_it_iM_i\equiv r_i\pmod {m_i}\)。

三、扩展中国剩余定理

考虑 \(m_i\) 不互质的情况。

设当前求解到第 \(i\) 个方程,前 \(i-1\) 个方程的最小解为 \(X\),\(\text{lcm}(m_1,m_2,\cdots,m_{i-1})=M\)。则前 \(i-1\) 个方程的通解为 \(X+tM\)(\(t\) 为任意非负整数)。

考虑第 \(i\) 个方程,现在要找一个 \(t\),使得 \(X+tM\equiv r_i\pmod {m_i}\)。

移项得:\(tM\equiv r_i-X\pmod {m_i}\)。进一步转化为:\(tM+pm_i=r_i-X\)。显然这是一个不定方程,可以用 exgcd 求解。

解出最小的 \(t\) 后,更新 \(X=X+tM\),\(M=\text{lcm}(M,m_i)\)。

最后为保证 \(X\) 最小,还需对 \(M\) 取模。

//Luogu P4777
#include<bits/stdc++.h>
#define int long long
#define LLL __int128 //过程中某个地方会炸。或改用快速乘。
using namespace std;
const int N=1e5+5;
int n,m[N],r[N],M;
int exgcd(int a,int b,int &x,int &y){
if(!b) return x=1,y=0,a;
int d=exgcd(b,a%b,x,y);
int z=x; x=y,y=z-y*(a/b);
return d;
}
int exCRT(int n){
int M=m[1],X=r[1];
for(int i=2;i<=n;i++){
int a=M,b=m[i],c=r[i]-X,x,y,d=exgcd(a,b,x,y),t;
if(c%d) return -1;
a/=d,b/=d,c/=d,t=((LLL)x*c%b+b)%b;
X+=t*M,M*=m[i]/d,X=(X+M)%M;
}
return X;
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&m[i],&r[i]);
printf("%lld\n",exCRT(n));
return 0;
}

「算法笔记」CRT 与 exCRT的更多相关文章

  1. 「算法笔记」快速数论变换(NTT)

    一.简介 前置知识:多项式乘法与 FFT. FFT 涉及大量 double 类型数据操作和 \(\sin,\cos\) 运算,会产生误差.快速数论变换(Number Theoretic Transfo ...

  2. 「算法笔记」树形 DP

    一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...

  3. 「算法笔记」2-SAT 问题

    一.定义 k-SAT(Satisfiability)问题的形式如下: 有 \(n\) 个 01 变量 \(x_1,x_2,\cdots,x_n\),另有 \(m\) 个变量取值需要满足的限制. 每个限 ...

  4. 「算法笔记」Polya 定理

    一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...

  5. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

  6. 「算法笔记」旋转 Treap

    一.引入 随机数据中,BST 一次操作的期望复杂度为 \(\mathcal{O}(\log n)\). 然而,BST 很容易退化,例如在 BST 中一次插入一个有序序列,将会得到一条链,平均每次操作的 ...

  7. 「算法笔记」FHQ-Treap

    右转→https://www.cnblogs.com/mytqwqq/p/15057231.html 下面放个板子 (禁止莱莱白嫖板子) P3369 [模板]普通平衡树 #include<bit ...

  8. 「算法笔记」Min_25 筛

    戳 这里(加了密码).虽然写的可能还算清楚,但还是不公开了吧 QwQ. 真的想看的 私信可能会考虑给密码 qwq.就放个板子: //LOJ 6053 简单的函数 f(p^c)=p xor c #inc ...

  9. 「算法笔记」快速傅里叶变换(FFT)

    一.引入 首先,定义多项式的形式为 \(f(x)=\sum_{i=0}^n a_ix^i\),其中 \(a_i\) 为系数,\(n\) 为次数,这种表示方法称为"系数表示法",一个 ...

随机推荐

  1. SpringBoot Logback 日志配置

    目录 前言 日志格式 日志输出 日志轮替 日志级别 日志分组 小结 前言 之前使用 SpringBoot 的时候,总是习惯于将日志框架切换为 Log4j2,可能是觉得比较靠谱,也可能年龄大了比较排斥新 ...

  2. 【Linux】【Basis】文件

    refer to: https://en.wikipedia.org/wiki/POSIX refer to: https://en.wikipedia.org/wiki/Unix_file_type ...

  3. maven管理本地jar包

    maven作为包管理工具,好处不必多说.但是有些情况,比如需要引入第三方包,如快递鸟,支付宝,微信等jar包(当然有可能直接提供maven依赖),如果直接下载到本地之后,怎么整合到自己的maven工程 ...

  4. 【力扣】188. 买卖股票的最佳时机 IV

    给定一个整数数组 prices ,它的第 i 个元素 prices[i] 是一支给定的股票在第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你最多可以完成 k 笔交易. 注意:你不能同时参 ...

  5. 深入分析 Java ZGC

    传统的垃圾回收 CMS 与 G1 停顿时间瓶颈 ZGC 概览 深入 ZGC 原理 标记 Marking 着色指针 Reference Coloring Relocation 重映射和读屏障 Remap ...

  6. Flutter 中如何优雅的实现多渠道打包(埋点统计系列)

    我是 Zero,脑图先奉上 先赞后看,更新永不断 只要你关注 Flutter,这篇文章你绝对用得着,==> 强烈建议收藏 多渠道打包介绍 多渠道打包的主要作用是满足产品的运营需求,统计渠道和活动 ...

  7. DIgSILENT PowerFactory 15.1.7 破解过程

    将dll文件复制到安装路径下:

  8. M函数目录(Power Query 之 M 语言)

    2021-12-11更新 主页(选项卡) 管理列(组) 选择列 选择列Table.SelectColumns 删除列 删除列Table.RemoveColumns 删除其他列Table.SelectC ...

  9. 『学了就忘』Linux系统管理 — 86、查看系统资源相关命令

    目录 1.vmstat命令 2.dmesg命令 3.free命令 4.查看CPU信息 5.查看本机登陆用户信息 (1)w命令 (2)who命令 6.uptime命令 7.查看系统与内核相关信息 1.v ...

  10. CF749B Parallelogram is Back 题解

    Content 给出平行四边形的三个顶点 \((x_1,y_1),(x_2,y_2),(x_3,y_3)\),求出所有可能的第四个顶点. 数据范围:\(\forall i\in[1,3],-1000\ ...