[笔记] CRT & exCRT

构造法

求多组\(x \equiv r_i (\bmod d_i)\)的解,\(d_i\)互质

余数\((r_i = remainder)\),除数\((d_i=divisor)\)

我们想啊,如果我们能找到一个数 \(k1\equiv1(mod\text{ }3)\)是 \(5\) 和 \(7\) 的倍数

一个数 $k2\equiv1(mod\text{ }5) $是\(3\)和\(7\)的倍数

一个数 $k3\equiv1(mod\text{ }7) $是\(3\)和\(5\)的倍数

那么这样的话我们的答案就是 \(k1*2+k2*3+k3*2\)

这样的话就是如何求这三个数了

首先我们求出 \(3,5,7\) 的$ lcm=105$

之后令

\(x1=105/3=35,x2=105/5=21,x3=105/7=15\)

我们可以得到三个线性同余方程

\(35a\equiv1(mod\text{ }3)\)

\(21b\equiv1(mod\text{ }5)\)

\(15c\equiv1(mod\text{ }7)\)

直接上扩欧就行了

所以$ k1=35a=35*2=70$

\(k2=21b=21∗1=21\)

\(k3=15c=15∗1=15\)

之后我们的答案就是

\((k1∗2+k2∗3+k3∗2)\bmod lcm=23\)

曹冲养猪

板子from wzx(我的构造法过不了,不过有了扩欧也不想用这个方法了)

#include<iostream>
#include<cstdio>
#include<cstring>
#define LL long long
#define re register
#define maxn 25
using namespace std;
inline LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1,y=0;
return a;
}
LL r=exgcd(b,a%b,y,x);
y-=a/b*x;
return r;
}
inline LL read()
{
char c=getchar();
LL x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
LL a[maxn],b[maxn];
LL x,y;
int n;
LL lcm=1;
int main()
{
n=read();
for(re int i=1;i<=n;i++)
{
b[i]=read();
a[i]=read();
lcm*=b[i];
}
LL ans=0;
for(re int i=1;i<=n;i++)
{
LL xx=lcm/b[i];
LL r=exgcd(xx,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
ans=(ans+x*xx*a[i]%lcm)%lcm;
}
cout<<ans<<endl;
return 0;
}

扩欧法

\[\begin{cases}
x &\equiv& r_1 \pmod{d_1}\\
x & \equiv& r_2 \pmod{d_2}\\
&\vdots\\
x & \equiv& r_n \pmod{d_n}
\end{cases}\]

此时如果\(d_1,d_2,\dots,d_n\)不互质怎么办?

观察两个同余式

  • $x\equiv r_1 \pmod{d_1} $
  • \(x\equiv r_2 \pmod{d_2}\)

可以化为

  • \(x=k_1d_1 + r_1\)
  • \(x=k_2d_2+r_2\)

因此

  • \(k_2d_2+r_2=k_1d_1+r_1\)
  • \(k_2d_2-k_1d_1=r_1-r_2\)

是不是有点像\(ax+bx=c\)

于是我们可以解出来

  • \(k_2 ^{'} d_2+k_1 ^{'} d_1=gcd(d_1,d_2)\)

并乘上\((r_1-r_2)/gcd(d_1,d_2)\)得到之前式子的解

  • \(k_1=k_1 ^{'} \cdot (r_1-r_2)/gcd(d_1,d_2)\)

但是得\(gcd(d_1,d_2)|(r_1-r_2)\),不然是得不到通解的

因为是带着一个负号的,所以得到

  • \(x_0= -k_1d_1+r_1\)

得到新方程\(x\equiv x_0 \pmod{ lcm(d_1,d_2)}\)

好的,开始,抠细节

  • 首先,最后要取模\(lcm(d1,d2)\),快速乘的时候忘记了,挂掉x1
  • 快速乘里面不能有负数,挂掉x2
  • 快速乘也要取模\(lcm(d_1,d_2)\),挂掉x3
  • \(lcm(d_1,d_2)\)应该这么写,\(d_1 /gcd(d_1,d_2)\cdot d_2\),而不是\(d_1 \cdot d_2 / gcd(d_1,d_2)\),挂掉x4
  • 把除号放里面,不然有逆元,(其实是因为模了一个不该模的东西)挂掉x5

代码

#include <iostream>
#include <cstdio>
#include <algorithm> using namespace std; typedef long long ll; const int N = 1e5 + 10; ll n, x, y;
ll d[N], r[N]; ll mul(ll a, ll b, ll p){//龟速乘
int f = 1;
if(a < 0) f = -f, a = -a;
if(b < 0) f = -f, b = -b;
ll w = 0;
while(b){
if(b & 1)
w = (w + a) % p;
b >>= 1;
a = (a + a) % p;
}
return w * f;
} ll exgcd(ll a, ll b){//扩欧
ll ans, t;
if(b == 0){
x = 1;
y = 0;
return a;
} else {
ans = exgcd(b, a % b);
t = x;
x = y;
y = t - a / b * y;
} return ans;
} ll exCRT(){ for(int i = 2; i <= n; ++i){
ll C = r[1] - r[i];
ll D = exgcd(d[i], d[1]);
if(C % D) return -1;
ll k1 = mul(y , c / D, d[1] / D * d[i] );
ll x0 = mul(-k1 , d[1], d[1] / D * d[i] ) + r[1];
d[1] = d[1] / D * d[i], r[1] = x0;
r[1] = (r[1] % d[1] + d[1]) % d[1];//先模一遍,让绝对值小于,然后处理
}
return r[1];
} int main(){
scanf("%lld", &n);
for(int i = 1; i <= n; ++i){
scanf("%lld %lld", &d[i], &r[i]);
}
long long ans = exCRT();
printf("%lld", ans);
return 0;
}

我知道写的超级丑,比不上fym

[笔记] CRT & exCRT的更多相关文章

  1. CRT & EXCRT 学习笔记

    这玩意解决的是把同余方程组合并的问题. CRT的核心思想和拉格朗日插值差不多,就是构造一组\(R_i\)使得$\forall i,j(i \neq j) $ \[R_im_i = 1, R_im_j ...

  2. CRT&EXCRT学习笔记

    非扩展 用于求解线性同余方程组 ,其中模数两两互质 . 先来看一看两个显然的定理: 1.若 x \(\equiv\) 0 (mod p) 且 y \(\equiv\) 0 (mod p) ,则有 x+ ...

  3. CRT&EXCRT 中国剩余定理及其扩展

    前言: 中国剩余定理又名孙子定理.因孙子二字歧义,常以段子形式广泛流传. 中国剩余定理并不是很好理解,我也理解了很多次. CRT 中国剩余定理 中国剩余定理,就是一个解同余方程组的算法. 求满足n个条 ...

  4. CRT && exCRT模板

    CRT从各种方面上都吊打exCRT啊...... 短,好理解... 考虑构造bi使得bi % pi = ai,bi % pj = 0.然后全加起来就行了. 显然bi的构造就是ai * (P/pi) * ...

  5. crt,excrt学习总结

    \(crt,Chinese\ Remainder\ Theorem\) 概述 前置技能:同余基础性质,\(exgcd\). \(crt\),中国剩余定理.用于解决模数互质的线性同余方程组.大概长这样: ...

  6. [note]CRT&exCRT

    中国剩余定理 别人的blog 假设现在有关于x的同余方程组(p1,p2均为质数) \(x=a_1\pmod {p_1}\) \(x=a_2\pmod {p_2}\) 可以转化成如下形式 \(x=a_1 ...

  7. BZOJ 3782: 上学路 Lucas+ExCRT+容斥+dp

    其实呢,扩展中国剩余定理还有一种理解方式:就是你有一坨东西,形如:$A[i]\equiv B[i](mod$ $P[i])$. 对于这个东西,你可以这么思考:如果最后能求出一个解,那么这个解的增量一定 ...

  8. BZOJ 1951: [Sdoi2010]古代猪文 ExCRT+欧拉定理+Lucas

    欧拉定理不要忘记!! #include <bits/stdc++.h> #define N 100000 #define ll long long #define ull unsigned ...

  9. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

随机推荐

  1. Leetcode(38)-报数

    报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数.其前五项如下: 1. 1 2. 11 3. 21 4. 1211 5. 111221 1 被读作  "one 1&quo ...

  2. 设计模式六大原则 All In one

    设计模式六大原则 All In one 开闭原则: 对扩展开放,对修改关闭; 设计模式的六大原则: 0.总原则-开闭原则 对扩展开放, 对修改封闭; 在程序需要进行拓展的时候, 不能去修改原有的代码, ...

  3. Flutter Widgets

    Flutter Widgets Flutter 组件 Syncfusion Flutter Widgets 所有组件均支持即装即用的 Android,iOS和 Web not free https:/ ...

  4. How to enable HTTPS for local development in macOS using Chrome

    How to enable HTTPS for local development in macOS using Chrome HTTPS, macOS, Chrome local HTTPS htt ...

  5. SQL All In One

    SQL All In One Structured Query Language SQL is an ANSI (American National Standards Institute) stan ...

  6. 行业动态 | Apache Pulsar 对现代数据堆栈至关重要的四个原因

    与 Kafka 相比,Pulsar 的架构使它在跨地域复制.扩展.多租户和队列等方面具有重要的优势.   1 月 27 日,DataStax 宣布收购Kesque(Pulsar 即服务),加入到了 P ...

  7. Python爬虫_糗事百科

    本爬虫任务: 爬虫糗事百科网站(https://www.qiushibaike.com/)--段子版块中所有的[段子].[投票数].[神回复]等内容 步骤: 通过翻页寻找url规律,构造url列表 查 ...

  8. [Android搞机]修改build.prop解决类原生无法链接12、13信道wifi问题

    最近xda找包刷了个机,发现没法搜到12.13信道.所有未本地化的类原生都有此问题. root后打开/system/build.prop 可以用 在build.prop中加入以下几句,重启即可连接12 ...

  9. 敏捷史话(七):从程序员、作家到摇滚乐手——Andy Hunt的多面人生

    与其说 Andy Hunt 是敏捷宣言的创始人,不如说他是一名专业作家来得更为合适.他的<实用程序员><程序员修炼之道:从小工到专家><编程 Ruby:实用程序员指南&g ...

  10. Java基本概念:封装

    一.简介 描述: 生活中,我们要看电视,只需要按一下开关和换台就可以了.我们没有有必要了解电视机内部的结构. 制造厂家为了方便我们使用电视,把复杂的内部细节全部封装起来,只给我们暴露简单的接口,比如电 ...