清除一个误区

虽然中国剩余定理和拓展中国剩余定理只差两个字,但他俩的解法相差十万八千里,所以会不会CRT无所谓

用途

求类似$$\begin{cases}x \equiv b_{1}\pmod{a_{1}} \\x \equiv b_{2}\pmod{a_{2}} \\...\\x \equiv b_{n}\pmod{a_{n}} \\ \end{cases}$$的线性同余方程组的解

具体过程

假设现在我们只有两个同余方程$$x \equiv b_{1}\pmod{a_{1}}$$ $$x \equiv b_{2}\pmod{a_{2}}$$

改写它们得$$x=a_{1}k_{1}+b_{1}                  ①$$ $$x=a_{2}k_{2}+b_{2}$$

联立$$a_{1}k_{1}+b_{1}=a_{2}k_{2}+b_{2}$$

所以$$a_{1}k_{1}=b_{2}-b_{1}+a_{2}k_{2}$$

记$$c=gcd(a_{1},a_{2})$$ $$d_{1}=\frac{a_{1}}{c}$$ $$d_{2}=\frac{a_{2}}{c}$$

两边同除以$c$得$$d_{1}k_{1}=\frac{b_{2}-b_{1}}{c}+d_{2}k_{2}$$

即$$d_{1}k_{1} \equiv \frac{b_{2}-b_{1}}{c}\%d_{2}\pmod{d_{2}}$$

显然,方程组有解的条件是$c|(b_{2}-b_{1})$

为什么要在这个时候取模$\%d_{2}$?因为之后取模的时候模数和被模数已经不互质了

记$d_{1}$在模$d_{2}$意义下的逆元为$p$,两边同乘$p$得$$k_{1} \equiv \frac{p(b_{2}-b_{1})}{c}\%d_{2} \pmod{d_{2}}$$

即$$k_{1} = \frac{p(b_{2}-b_{1})}{c}\%d_{2}+d_{2}*y$$

带入①式得$$x=\frac{p(b_{2}-b_{1})}{c}\%d_{2}*a_{1}+d_{2}a_{1}y+b_{1}$$

即$$x \equiv \frac{p(b_{2}-b_{1})}{c}\%d_{2}*a_{1}+b_{1}\pmod{a_{1}d_{2}}$$

注意,上式中的$a_{1}$万万不可乘到$\%d_{2}$前面

所以我们就弄出了一个新的同余方程。这个方程也可以写成$$x \equiv b \pmod a$$其中$$b=(inv(\frac{a_{1}}{(a_{1},a_{2})},\frac{a_{2}}{(a_{1},a_{2})})*\frac{b_{2}-b_{1}}{(a_{1},a_{2})}\%\frac{a_{2}}{(a_{1},a_{2})}*a_{1}+b_{1})$$ $$a=\frac{a_{1}a_{2}}{(a_{1},a_{2})}$$

其中$inv(m,n)$表示$m$在模$n$意义下的逆元,$(m,n)$表示$m$和$n$的最大公约数

然后把新求出的方程和后面的方程联立,迭代求解,直到只剩一个方程

精度问题

毫无疑问的是,在求解方程组的时候很容易爆$long long$,那该怎么办呢?

__int128 快(龟)速(速)乘(乘)是个不错的主意。

何为快速乘?

就是一种和快速幂类似的东西,利用二进制在log时间内求出两个数相乘对另一个数取模的结果并且不会爆long long

但要注意的是,千万不要让负数出现在快速乘里面,尤其是被拆分的那个乘数,会死循环的

 int mul(int x,int k,int mod) {
ll ans=;
while(k) {
if(k&)(ans+=x)%=mod;
k>>=;
(x<<=)%=mod;
}
return ans;
}

快速乘

题目

洛谷【模板】扩展中国剩余定理(EXCRT)

 #include<bits/stdc++.h>
using namespace std;
#define INF 0x7fffffff
#define ME 0x7f
#define FO(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define fui(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define fdi(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define fel(i,a) for(register int i=hd[a];i;i=dg[i].nxt)
#define ll long long
#define int long long
#define MEM(a,b) memset(a,b,sizeof(a))
#define maxn 100010
ll n;
ll a[maxn],b[maxn],a0,b0;
template<class T>
inline T read(T &n){
n=;int t=;double x=;char ch;
for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());(ch=='-')?t=-:n=ch-'';
for(ch=getchar();isdigit(ch);ch=getchar()) n=n*+ch-'';
if(ch=='.') for(ch=getchar();isdigit(ch);ch=getchar()) n+=(ch-'')/x,x*=;
return (n*=t);
}
template<class T>
T write(T n){
if(n<) putchar('-'),n=-n;
if(n>=) write(n/);putchar(n%+'');return n;
}
template<class T>
T writeln(T n){write(n);putchar('\n');return n;}
int exgcd(int a,int b,int &x,int &y){
if(!b)return a+((x=)*(y=));
int xx,yx,z;z=exgcd(b,a%b,xx,yx);
x=yx,y=xx-a/b*yx;return z;
}
int gcd(int a,int b){if(!b)return a;return gcd(b,a%b);}
int mul(int x,int k,int mod){
ll ans=;
while(k){
if(k&)(ans+=x)%=mod;
k>>=;
(x<<=)%=mod;
}
return ans;
}
signed main(){
read(n);
fui(i,,n,)read(a[i]),read(b[i]);
a0=a[],b0=b[];
fui(i,,n,){
int c=gcd(a0,a[i]),d1=a0/c,d2=a[i]/c,p,x,y;
int a1=a0,a2=a[i],b1=b0,b2=b[i];
if(((b2-b1)/c*c)^(b2-b1))return *writeln(-);
exgcd(d1,d2,p,y);((p%=d2)+=d2)%=d2;
x=mul(p,(((b2-b1)/c)%d2+d2)%d2,d2)*a1+b1;
y=a1*d2;b0=x,a0=y;((b0%=a0)+=a0)%=a0;
}
int x,y;exgcd(,a0,x,y);
((x%=a0)+=a0)%=a0;
x=mul(x,b0,a0);
writeln(x);
return ;
}

AC代码

 好像还有NOI2018屠龙勇士?23333先等我去A掉它

拓展中国剩余定理(exCRT)摘要的更多相关文章

  1. C++实现,拓展中国剩余定理——解同余方程组(理论证明和代码实现)

    拓展中国剩余定理 前言 记得半年前还写过关于拓展中国剩余定理的博客...不过那时对其理解还不是比较深刻,写的也比较乱. 于是趁学校复习之机,再来重温一下拓展中国剩余定理(以下简称ExCRT) 记得半年 ...

  2. 拓展中国剩余定理(ex_crt)

    一般来讲,crt(中国剩余定理)比较常见,而ex_crt(拓展中国剩余定理)不是很常用 但是noi 2018偏偏考了这么个诡异的东西... 所以这里写一个ex_crt模板 模型: 求一个x满足上述方程 ...

  3. 扩展中国剩余定理 (exCRT) 的证明与练习

    原文链接https://www.cnblogs.com/zhouzhendong/p/exCRT.html 扩展中国剩余定理 (exCRT) 的证明与练习 问题模型 给定同余方程组 $$\begin{ ...

  4. 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结

    中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...

  5. 扩展中国剩余定理 (ExCRT)

    扩展中国剩余定理 (ExCRT) 学习笔记 预姿势: 扩展中国剩余定理和中国剩余定理半毛钱关系都没有 问题: 求解线性同余方程组: \[ f(n)=\begin{cases} x\equiv a_1\ ...

  6. E - Two Arithmetic Progressions(CodeForces - 710D)(拓展中国剩余定理)

    You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such ...

  7. 2019牛客暑期多校训练营(第十场) Han Xin and His Troop (高精度+拓展中国剩余定理)

    题意 裸题 思路 题中的模数之间并不互质,所以应该用拓展中国剩余定理. 但是交上去会炸,__int128过不了,所以用高精度的板子或者java大数都挺好过的. 这里推荐java大数,因为高精度板子用起 ...

  8. 扩展中国剩余定理 exCRT 学习笔记

    前言 由于 \(\{\mathrm{CRT}\}\subseteq\{\mathrm{exCRT}\}\),而且 CRT 又太抽象了,所以直接学 exCRT 了. 摘自 huyufeifei 博客 这 ...

  9. 中国剩余定理(excrt) 模板

    excrt板子题 #include <cmath> #include <cstdio> #include <cstring> #include <algori ...

随机推荐

  1. A总结

    Alpha 答辩总结 评审表 组名 格式 内容 ppt 演讲 答辩 总计 天机组 15 15 14 15 14 73 PMS 16 16 15 15 16 78 日不落战队 16 16 16 15 1 ...

  2. 05 方法与数组笔记【JAVA】

    ---恢复内容开始--- 1:方法(掌握) (1)方法:就是完成特定功能的代码块. 注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法. (2)格式: 修饰符 返回值类型 方法名(参数类 ...

  3. jedispool资源释放

    我的天啊,这几天要被jedis逼疯了,网上好多资料并没有介绍jedis链接释放不了的方法,我确定他们那些老人肯定知道都,就是不说,你们说气人不.还有要吐槽哈jedis源码开发的那些家伙,怎么写的代码, ...

  4. java常见编码

    摘自:http://www.cnblogs.com/yaya-yaya/p/5768616.html 红色 主要点    灰色 内容      绿色  知识点    橘色 补充内容 几种常见的编码格式 ...

  5. vis.js绘图库的一个BUG以及源码修正

    1. BUG 1.1 BUG触发情况 在使用vis.js绘图时,加入两个节点A和B之间既存在一条从A指向B的边,同时也存在一条从B指向A的边,那么这个绘图库就会崩溃. 1.2 BUG解析 vis.js ...

  6. leetcode Database4

    一.Department Top Three Salaries The Employee table holds all employees. Every employee has an Id, an ...

  7. PHP4个载入语句的区别

    4个载入语句的区别 include和require的区别: include载入文件失败时(即没有找到该文件),报一个“提示错误”,然后继续执行后续代码: requre载入文件失败时,报错并立即终止执行 ...

  8. BZOJ2729 HNOI2012排队(组合数学+高精度)

    组合入门题.高精度入门题. #include<iostream> #include<cstdio> #include<cstdlib> #include<cs ...

  9. hihoCoder 1631 Cats and Fish(ACM-ICPC北京赛区2017网络同步赛)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 There are many homeless cats in PKU campus. They are all happy ...

  10. Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流)

    Libre 6004 「网络流 24 题」圆桌聚餐(网络流,最大流) Description 假设有来自n个不同单位的代表参加一次国际会议.每个单位的代表数分别为 ri.会议餐厅共有m张餐桌,每张餐桌 ...