中国剩余定理CRT

中国剩余定理是要求我们解决这样的一类问题:

\[\begin{cases}x\equiv a_1\pmod {b_1} \\x\equiv a_2 \pmod{b_2}\\...\\x\equiv a_n\pmod{b_n} \end{cases}
\]

其中\(b_1,b_2,...,b_n\)互质。

我们先令\(m=\prod_{i=1}^{n}b_i,w_i=m/b_i\)

那么有\(gcd(m,w_i)==1\)

我们对于\(w_ix'+my'= 1\)解出来\(x',y'\)后

\(w_ix'a_i\equiv a_i\pmod {b_i}\)

所以现在就相当于解\(n=\sum_{i=1}^n w_ix'a_i\pmod m\)

一道例题 TJOI2009猜数字

题目链接:戳我

CRT的模板

有两点需要注意——一个是输入的数可能会有负数,二是乘法的时候可能会乘爆,需要用快速乘qwq

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define MAXN 1010
using namespace std;
int n;
long long a[MAXN],b[MAXN];
inline ll fmul(ll x,ll y,ll mod)
{
ll cur_ans=0;
while(y>0)
{
if(y&1)cur_ans=(cur_ans+x)%mod;
x=(x+x)%mod;
y>>=1;
}
return cur_ans;
}
inline void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0){y=0,x=1;return;}
exgcd(b,a%b,x,y);
int cur=x;
x=y;
y=cur-a/b*y;
}
inline ll china()
{
long long M=1,cur_ans=0,x,y;
for(int i=1;i<=n;i++) M*=b[i];
for(int i=1;i<=n;i++)
{
long long w=M/b[i];
exgcd(w,b[i],x,y);
x=(x%b[i]+b[i])%b[i];
cur_ans=(cur_ans+fmul(fmul(w,x,M),a[i],M))%M;
}
return (cur_ans+M)%M;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
for(int i=1;i<=n;i++) a[i]=(a[i]%b[i]+b[i])%b[i];
printf("%lld\n",china());
return 0;
}

拓展中国剩余定理EXCRT

就是\(b_i\)不互质版本的......但是和中国剩余定理好像没有太大的关系qwq

我们假设已经解决了前k-1个方程,他们的解为ans,设\(m=\prod_{i=1}^{k-1}b_i\)。那么我们可以确定前k-1个方程的通解是\(ans+t*m\)。

现在的任务就是寻找一个t,使得\(ans+t*m\equiv a_i\pmod{b_i}\)

也就是\(t*m\equiv a_i-ans\pmod{b_i}\)

其实就是解\(a\equiv b\pmod {p}\)即\(ax+py=b\)的\(x',y'\)的解。

\(t=x'/gcd(m,b_i)*(a_i-ans)\)

\(ans=(ans+tm)\mod (\prod_{i=1}^{k-1}b_i)\)

一道模板

题目链接:戳我

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
#define ll long long
using namespace std;
int n;
long long a[MAXN],b[MAXN];
inline ll fmul(ll x,ll y,ll mod)
{
ll cur_ans=0;
while(y)
{
if(y&1) cur_ans=(cur_ans+x)%mod;
x=(x+x)%mod;
y>>=1;
}
return cur_ans;
}
inline ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0)
{
y=0,x=1;
return a;
}
ll ans=exgcd(b,a%b,x,y);
ll cur=x;
x=y;
y=cur-(a/b)*y;
return ans;
}
inline void solve()
{
ll ans=a[1],m=b[1],x,y;
for(int i=2;i<=n;i++)
{
ll B=((a[i]-ans)%b[i]+b[i])%b[i];
ll gcd=exgcd(m,b[i],x,y);
x=fmul(x,B/gcd,b[i]);
ans+=x*m;
m*=b[i]/gcd;
ans=(ans+m)%m;
}
printf("%lld\n",ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld%lld",&b[i],&a[i]);
// for(int i=1;i<=n;i++) printf("%lld %lld\n",a[i],b[i]);
solve();
return 0;
}

CRT和EXCRT简单学习笔记的更多相关文章

  1. OI数学 简单学习笔记

    基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...

  2. Log4j简单学习笔记

    log4j结构图: 结构图展现出了log4j的主结构.logger:表示记录器,即数据来源:appender:输出源,即输出方式(如:控制台.文件...)layout:输出布局 Logger机滤器:常 ...

  3. Linux——帮助命令简单学习笔记

    Linux帮助命令简单学习笔记: 一: 命令名称:man 命令英文原意:manual 命令所在路径:/usr/bin/man 执行权限:所有用户 语法:man [命令或配置文件] 功能描述:获得帮助信 ...

  4. 扩展中国剩余定理(EXCRT)学习笔记

    扩展中国剩余定理(EXCRT)学习笔记 用途 求解同余方程组 \(\begin{cases}x\equiv c_{1}\left( mod\ m_{1}\right) \\ x\equiv c_{2} ...

  5. <<C++标准程序库>>中的STL简单学习笔记

    0. 内容为个人学习笔记, 仅供参考, 如有错漏, 欢迎指正! 1. STL中的所有组件都是由模板构成的, 所以其元素可以是任意型别的. 组件有: - 容器: 管理某类对象的集合. 不同的容器有各自的 ...

  6. Mongoose简单学习笔记

    1.1 名词解释 Schema : 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model : 由Schema发布生成的模型,具有抽象属性和行为的数据库操作对 Entity : 由Mo ...

  7. Linux——bash应用技巧简单学习笔记

    本人是看的lamp兄弟连的视频,学习的知识做一下简单,如有错误尽情拍砖. 命令补齐 命令补齐允许用户输入文件名起始的若干个字 母后,按<Tab>键补齐文件名. 命令历史 命令历史允许用户浏 ...

  8. Oracle简单学习笔记

    创建用户 CREATE USER username identified by password;//这是最简单的用户创建SQL语句. CREATE USER username identified ...

  9. Linux——软件包简单学习笔记

    Linux中的是那种软件包:  (这里学习是基于redHat的Cent-OS) 1: 二进制软件包管理(RPM.YUM) 2:源代码包安装 3: 脚本安装(Shell或Java脚本) 一: 二进制软件 ...

随机推荐

  1. 15-js提交表单的简单检测实例

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  2. dede数据库内容替换,去掉文章内容中的img标签

    1.织梦已经给我们准备好了数据库内容替换工具,在采集->批量维护->数据库内容替换 2.织梦的文章内容一般在放在dede_addonarticle表body字段中. (1).选择好数据表和 ...

  3. 【SQL模板】四.插入/更新 列模板TSQL

    ---Name: 插入/更新 列模板.sql ---Purpose: 用于更新 数据库中 列 的脚本模板 ---Author: xx ---Time: 2015-12-18 10:26:06 ---R ...

  4. POJ3687.Labeling Balls 拓扑排序

    Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13201 Accepted: 3811 Descr ...

  5. Jmeter中控制某一段脚本失败后重复执行,并在每个HTTP Request名字中加上循环次数

    ================================================== 1.While Controller之前有一个BeanShell Sampler,用于Init N ...

  6. 模型参数_grid

    from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.preproc ...

  7. 硬件GPIO,UART,I2C,SPI电路图

  8. GoogleStyle格式化代码

    <div class="iteye-blog-content-contain" style="font-size: 14px"></div&g ...

  9. 将Excel导入DataGridView 中的"select * from [Sheet1$]"中[ ]里面表单名的动态获取

    Sheet1$是Excel默认的第一个表名,如果改动:select * from [Sheet1$]"将查询失败,因此应根据选择自动获取excel表名: OpenFileDialog ofd ...

  10. Java(Android)线程池[转]

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...