中国剩余定理

给出以下的一元线性同余方程组:

$\Large(s):\left\{
\begin{aligned}
x\equiv a_1\ (mod\ m_1)\\
x\equiv a_2\ (mod\ m_2)\\
\vdots\ \ \ \ \ \ \ \ \ \ \ \ \\
x\equiv a_n\ (mod\ m_n)
\end{aligned}
\right.$

假设整数$m_1,m_2……,m_n$两两互质,则对任意的整数:$a_1,a_2……,a_n$,方程组有解
设$M=m_1m_2……m_n$并且$M_i=M/m_i$
则解为$x\equiv(a_1M_1M_1^{-1}+a_2M_2M_2^{-1}+……+a_nM_nM_n^{-1})mod\ M$

证明:

因为$x\equiv(a_iM_iM_i^{-1})mod\ m_i\ \ i\in\{1,2,……,n\}$  $(MiMi^-1)\%mi=1$

又因为$a_jM_jM_j^{-1}\equiv 0\ mod\ m_i\ \ \forall i\neq j$(如果i!=j,则Mj是mi的倍数)

所以 $x\equiv(a_1M_1M_1^{-1}+a_2M_2M_2^{-1}+……+a_nM_nM_n^{-1})mod\ m_i\ \ i\in\{1,2,……,n\}$

因为mi互素

所以$x\equiv(a_1M_1M_1^{-1}+a_2M_2M_2^{-1}+……+a_nM_nM_n^{-1})mod\ M$

#include<cstdio>
#define ll long long
inline void exgcd(ll a,ll b,ll &x,ll &y){//a,b,x,y同ax+by=gcd(a,b)中的a,b,x,y
if(!b){
x=,y=;return;
}
ll t;
exgcd(b,a%b,x,y);
t=x,x=y,y=t-(a/b)*y;
}
inline ll Inverse(ll a,ll p){//求a模p的乘法逆元
ll x,y;
exgcd(a,p,x,y);
return x;
}
inline ll CRT(ll a[],ll m[],ll n){//求解同余方程组
ll M=,_Mi,Mi,ans=;//_Mi为Mi的乘法逆元(%m[i]意义下的)
for(int i=;i<n;i++)M*=m[i];
for(int i=;i<n;i++){
Mi=M/m[i];
_Mi=Inverse(Mi,m[i]);
ans=(ans+Mi*_Mi*a[i])%M;
}
if(ans<)ans+=M;
return ans;//返回最小正整数解
}
int main(){
return ;
}

例题

韩信点兵

/******************************************************************
中国剩余定理
******************************************************************/
#include<cstdio>
#define ll long long
#define maxn 15
inline void exgcd(ll a,ll b,ll &x,ll &y){//a,b,x,y同ax+by=gcd(a,b)中的a,b,x,y
if(!b){
x=,y=;return;
}
ll t;
exgcd(b,a%b,x,y);
t=x,x=y,y=t-(a/b)*y;
}
inline ll Inverse(ll a,ll p){//求a模p的乘法逆元
ll x,y;
exgcd(a,p,x,y);
return x;
}
inline ll CRT(ll a[],ll m[],ll n,ll &M){//求解同余方程组
ll _Mi,Mi,ans=;//_Mi为Mi的乘法逆元(%m[i]意义下的)
for(int i=;i<n;i++)M*=m[i];
for(int i=;i<n;i++){
Mi=M/m[i];
_Mi=Inverse(Mi,m[i]);
ans=(ans+Mi*_Mi*a[i])%M;
}
if(ans<)ans+=M;
return ans;//返回最小正整数解
}
ll p[maxn],a[maxn];
ll M=,ans,n,m;
int main(){
// freopen("HanXin.in","r",stdin);
// freopen("HanXin.out","w",stdout);
scanf("%lld%lld",&n,&m);
for(int i=;i<m;i++){
scanf("%lld%lld",p+i,a+i);
}
ans=CRT(a,p,m,M);
if(ans>n)printf("-1");
else printf("%lld",(n-ans)%M);
return ;
}

扩展——求解模数不互质的线性方程组

$\Large (s):\left\{
\begin{aligned}
x\equiv a_1\ (mod\ m_1)\\
x\equiv a_2\ (mod\ m_2)\\
\vdots\ \ \ \ \ \ \ \ \ \ \ \ \\
x\equiv a_n\ (mod\ m_n)
\end{aligned}
\right.$

如果m1,m2……mn不互质,则中国剩余定理无法运用
这时我们可以对方程组进行转换,比如前两个方程可以变为:

$x=a_1+k_1m_1$和$x=a_2+k_2m_2$

则$a_2-a_1=k_1m_1-k_2m_2$

只有k1,k2是未知,我们用扩展欧几里得求出最小的k1(如果a2-a1%gcd(m1,m2)!=0,则无解)

求解最小k1:

设$q*m_1+y*m_2=gcd(m1,m2)$

用exgcd(m1/gcd(m1,m2),m2/gcd(m1,m2),q,y)解出最小q,

最小的$k_1=q*(a_2-a_1)/gcd(m_1,m_2)$;

带入$x=a_1+k_1m_1$可以求出满足前两个方程的解

这时,记当前x为x',

整个方程组的解x一定就满足$x\equiv x'(mod\ lcm(m_1,m_2))$

将这个方程加入方程组,重复上面步骤,每次消去一个方程,最后一个x'就是答案

注意:m1,m2,……,mn的最小公倍数不要爆容器

#include<cstdio>
#include<cstdlib>
#define ll long long
inline ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
inline ll lcm(ll a,ll b){
return a*b/gcd(a,b);
}
inline void exgcd(ll a,ll b,ll &x,ll &y){//a,b,x,y同ax+by=gcd(a,b)中的a,b,x,y
if(!b){
x=,y=;return;
}
ll t;
exgcd(b,a%b,x,y);
t=x,x=y,y=t-(a/b)*y;
}
inline void merge(ll a1,ll m1,ll a2,ll m2,ll &a3,ll &m3){//将方程x=a1+k1m1和x=a2+k2m2合并为x=a3+k3m3;
ll d=gcd(m2,m1),a=a2-a1,q,y;
if(a%d)exit();//无解
m3=lcm(m1,m2);
exgcd(m1/d,m2/d,q,y);
a3=a/d*q*m1+a1;
((a3%=m3)+=m3)%=m3;
}
inline ll solve(ll a[],ll m[],ll n){//求解同余方程组
ll a1=a[],m1=m[];
for(int i=;i<n;i++){
merge(a1,m1,a[i],m[i],a1,m1);
}
return (a1%m1+m1)%m1;//返回最小正整数解
}
int main(){
return ;
}

中国剩余定理CRT(孙子定理)的更多相关文章

  1. 【bzoj1951】【古代猪文】Lucas定理+欧拉定理+孙子定理

    (上不了p站我要死了,当然是游戏原画啊) Description (题面倒是很有趣,就是太长了) 题意: 一个朝代流传的猪文文字恰好为N的k分之一,其中k是N的一个正约数(可以是1和N).不过具体是哪 ...

  2. 《孙子算经》之"物不知数"题:中国剩余定理

    1.<孙子算经>之"物不知数"题 今有物不知其数,三三数之剩二,五五数之剩七,七七数之剩二,问物几何? 2.中国剩余定理 定义: 设 a,b,m 都是整数.  如果 m ...

  3. acm数论之旅--中国剩余定理

    ACM数论之旅9---中国剩余定理(CRT)(壮哉我大中华╰(*°▽°*)╯)   中国剩余定理,又名孙子定理o(*≧▽≦)ツ 能求解什么问题呢? 问题: 一堆物品 3个3个分剩2个 5个5个分剩3个 ...

  4. POJ 1006 中国剩余定理

    #include <cstdio> int main() { // freopen("in.txt","r",stdin); ; while(sca ...

  5. gcd,扩展欧几里得,中国剩余定理

    1.gcd: int gcd(int a,int b){ ?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题: ...

  6. ACM数论之旅9---中国剩余定理(CRT)(壮哉我大中华╰(*°▽°*)╯)

    中国剩余定理,又名孙子定理o(*≧▽≦)ツ 能求解什么问题呢? 问题: 一堆物品 3个3个分剩2个 5个5个分剩3个 7个7个分剩2个 问这个物品有多少个 解这题,我们需要构造一个答案 我们需要构造这 ...

  7. 29-中国剩余定理CRT

    https://blog.csdn.net/u010468553/article/details/38346195 中国剩余定理[数论] 2014年08月02日 12:55:59 阅读数:2351 中 ...

  8. 【bzoj3782】上学路线 dp+容斥原理+Lucas定理+中国剩余定理

    题目描述 小C所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M).小C家住在西南角,学校在东北角.现在有T个路口进行施工,小C不能通过这些路口.小C喜欢走最短的路径到达目的 ...

  9. NOI 2018 屠龙勇士 (拓展中国剩余定理excrt+拓展欧几里得exgcd)

    题目大意:略 真是一波三折的一道国赛题,先学了中国剩余定理,勉强看懂了模板然后写的这道题 把取出的宝剑攻击力设为T,可得Ti*x=ai(mod pi),这显然是ax=c(mod b)的形式 这部分用e ...

随机推荐

  1. vue项目打包后资源相对引用路径的和背景图片路径问题

    vue项目中若要使用相对路径来获得相应静态资源,需要修改以下内容来确保项目打包后能正常运行. 1.修改config => index.js => build => assetsPub ...

  2. 20.multi_case04

    import aiohttp import asyncio import ssl async def fetch(session, url): async with session.get(url,s ...

  3. Team Train Recorder 2.0

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 2019/10/4, solved 4/9, upsolved

  4. 笔记:使用Python解析JSON

    使用Python解析JSON json是一种轻量级的数据交换格式,易于阅读和编写. json函数具体作用描述 函数 具体描述作用 json.dumps 将python对象编码为JSON字符串 json ...

  5. tensorboard在Mac OS X系统环境下如何启动

    再次必须写一篇博客,一次来说明这打开tensorboard的艰难之路,遇到了好多错误,真的是走了好多弯路,最后还是解决了 一开始总是报错,不知道是为什么,其实还是自己没有看懂原理,就冲动的开始招呼画瓢 ...

  6. vc 识别移动硬盘 U盘,本地硬盘

    说明:有时候我们在做设备监控的时候,要识别一些链接设备,在使用函数GetDriveType的时候,U盘可以返回DRIVE_REMOVABLE,而本地硬盘硬盘和移动硬盘DRIVE_FIXED,因此还需要 ...

  7. C++ 系列:extern

    extern 作用1:声明外部变量现代编译器一般采用按文件编译的方式,因此在编译时,各个文件中定义的全局变量是互相透明的,也就是说,在编译时,全局变量的可见域限制在文件内部. 例1:创建一个工程,里面 ...

  8. html--图片背景兼容,兼容IE6

    在IE6中对图片格式png24支持度不高, 如果使用的图片格式是png24,则会导致透明效果无法正常显示 解决方法: 1.可以使用png8来代替png24,即可解决问题, 但是使用png8代替png2 ...

  9. pycharm远程调试和debug

    目的:     通过pycharm远程连接服务器,实现在pycharm上开发,代码同步到服务器(或者可以从服务器download到pycharm),利用服务器开发环境在pycharm上debug.   ...

  10. [JZOJ3167] 【GDOI2013模拟3】查税

    题目 描述 题目大意 维护一个有一次函数组成的序列 具体来说,对于位置xxx,现在的值为sx+zx∗(T−tx)s_x+z_x*(T-t_x)sx​+zx​∗(T−tx​) 有两个操作,修改某个位置上 ...