拓展中国剩余定理(exCRT)摘要
清除一个误区
虽然中国剩余定理和拓展中国剩余定理只差两个字,但他俩的解法相差十万八千里,所以会不会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;
}
快速乘
题目
#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)摘要的更多相关文章
- C++实现,拓展中国剩余定理——解同余方程组(理论证明和代码实现)
拓展中国剩余定理 前言 记得半年前还写过关于拓展中国剩余定理的博客...不过那时对其理解还不是比较深刻,写的也比较乱. 于是趁学校复习之机,再来重温一下拓展中国剩余定理(以下简称ExCRT) 记得半年 ...
- 拓展中国剩余定理(ex_crt)
一般来讲,crt(中国剩余定理)比较常见,而ex_crt(拓展中国剩余定理)不是很常用 但是noi 2018偏偏考了这么个诡异的东西... 所以这里写一个ex_crt模板 模型: 求一个x满足上述方程 ...
- 扩展中国剩余定理 (exCRT) 的证明与练习
原文链接https://www.cnblogs.com/zhouzhendong/p/exCRT.html 扩展中国剩余定理 (exCRT) 的证明与练习 问题模型 给定同余方程组 $$\begin{ ...
- 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结
中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...
- 扩展中国剩余定理 (ExCRT)
扩展中国剩余定理 (ExCRT) 学习笔记 预姿势: 扩展中国剩余定理和中国剩余定理半毛钱关系都没有 问题: 求解线性同余方程组: \[ f(n)=\begin{cases} x\equiv a_1\ ...
- E - Two Arithmetic Progressions(CodeForces - 710D)(拓展中国剩余定理)
You are given two arithmetic progressions: a1k + b1 and a2l + b2. Find the number of integers x such ...
- 2019牛客暑期多校训练营(第十场) Han Xin and His Troop (高精度+拓展中国剩余定理)
题意 裸题 思路 题中的模数之间并不互质,所以应该用拓展中国剩余定理. 但是交上去会炸,__int128过不了,所以用高精度的板子或者java大数都挺好过的. 这里推荐java大数,因为高精度板子用起 ...
- 扩展中国剩余定理 exCRT 学习笔记
前言 由于 \(\{\mathrm{CRT}\}\subseteq\{\mathrm{exCRT}\}\),而且 CRT 又太抽象了,所以直接学 exCRT 了. 摘自 huyufeifei 博客 这 ...
- 中国剩余定理(excrt) 模板
excrt板子题 #include <cmath> #include <cstdio> #include <cstring> #include <algori ...
随机推荐
- Scapy安装以及简单使用
Scapy安装以及简单使用 参考文档 scapy官方文档 前言 scapy是一个可以模拟发送报文的python程序,使用了它从此发包不愁. 安装 1.首先得安装Python2.7 在linux系统 ...
- Visual Studio 2013安装及简单的单元测试
Visual Studio 2013安装部分首先到观望下载了英文版和简体中文的语言包.但是更新语言包时总是失败,安装vs需要等待的时间也很大.后来重新装了一遍系统(这个卸载也很麻烦),从其他网站下了中 ...
- Python入门:for循环、while循环
Python中有两种循环,分别为:for循环和while循环. 1. for循环 for循环可以用来遍历某一对象(遍历:通俗点说,就是把这个循环中的第一个元素到最后一个元素依次访问一次).for循环的 ...
- FuelPHP 系列(四) ------ Validate 验证
一.可用规则: 1.required 不能为 null, false or empty string.: 2.required_with 关联某个字段,关联字段有值则该字段必须有值: 3.match_ ...
- spring not_support 该方法被事务方法调用时 不会加入spring事务 只是执行jdbc普通的事务
- Eclipse Job
Job可以我们基于Eclipse的Java程序中,我们有很多种方式提供多任务的实现.熟悉Java的朋友立即会想到Java的Thread类,这是Java中使 用最多的一个实现多任务的类.Eclipse平 ...
- 自动化运维—Ansible(上)
一:为什么选择Ansible 相对于puppet和saltstack,ansible无需客户端,更轻量级 ansible甚至都不用启动服务,仅仅只是一个工具,可以很轻松的实现分布式扩展 更强的远程命令 ...
- scheme 之门
scheme 之门 开始之前 这是一篇 Scheme 的介绍文章. Scheme 是一个 LISP 的方言, 相对于 Common LISP 或其他方言, 它更强调理论的完整和优美, 而不那么强调实用 ...
- Mac中把光盘转存为iso文件
因为Mac是类Unix的,因此,dd命令同样适用于Mac,那么,就很简单了,复习一下dd的用法而已 [xiaosilent@rmbp Volumes]$ drutil status Vendor Pr ...
- HDU 2255 KM算法 二分图最大权值匹配
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...