前言

中国剩余定理(也叫孙子定理)并不是很复杂,由于最近用到了,以前学的时候还不写博客,所以现在补一下

中国剩余定理(CRT)

问题

给出nnn个同余方程
x≡a1(modp1)x≡a2(modp2)⋅⋅⋅⋅⋅⋅⋅⋅x≡an(modpn)\begin{aligned} x&\equiv a_1\pmod{p_1}\\ x&\equiv a_2\pmod{p_2}\\ ··&\ \ \ \ \ ···\ \ \ \ \ \ \ \ ···\\ x&\equiv a_n\pmod{p_n}\\ \end{aligned} xx⋅⋅x​≡a1​(modp1​)≡a2​(modp2​)     ⋅⋅⋅        ⋅⋅⋅≡an​(modpn​)​
保证所有的ppp两两互质
求最小自然数解xxx

做法

我们令P=∏i=1npiP=\prod_{i=1}^n p_iP=i=1∏n​pi​
容易发现,x&lt;Px&lt;Px<P
证明,若现在求出一个xxx满足条件且x≥Px\ge Px≥P
那么(xmod&ThinSpace;&ThinSpace;P)(x\mod P)(xmodP)一定也满足条件且(xmod&ThinSpace;&ThinSpace;p)&lt;P(x\mod p)&lt;P(xmodp)<P
我们考虑对于一个限制x≡ai(modpi)x\equiv a_i\pmod{p_i}x≡ai​(modpi​),我们要进行一种操作,使得其它n−1n-1n−1个ppp的模意义下值不变,模pip_ipi​意义下的值从000变为aia_iai​
考虑如果我们加上的数是X∗PpiX*\frac{P}{p_i}X∗pi​P​形式的,那么我们就可以满足“其它n−1n-1n−1个ppp的模意义下值不变”,由于保证了所有ppp两两互质,所以Ppi̸≡0(modpi)\frac{P}{p_i}\not\equiv0\pmod{p_i}pi​P​̸​≡0(modpi​)
设Ppi≡vi(modpi)\frac{P}{p_i}\equiv v_i\pmod{p_i}pi​P​≡vi​(modpi​)
那么只要加上(aivi−1(modPpi))Ppi(a_iv_i^{-1}\pmod{\frac{P}{p_i}})\frac{P}{p_i}(ai​vi−1​(modpi​P​))pi​P​就可以满足这条限制
最后求出xxx后再模PPP就好了

例题

竟然有模板题。。。
洛谷P3868 [TJOI2009]猜数字
有个要注意的地方是这里的逆元应用扩展欧几里得(exGCD)求,另外由于模数过大,需要用到慢速乘(复杂度Θ(logn)\Theta(logn)Θ(logn)),可以用杜教乘优化(复杂度Θ(1)\Theta(1)Θ(1),我的这篇博客里有提到)

代码

ac代码(其实也是板子)

#include<cstdio>
#include<cctype>
#include<algorithm>
namespace fast_IO
{const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{if(x>=10)printe(x/10);putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{if(x<0)putchar('-'),printe(-x);else printe(x);
}
LL EXgcd(const LL a,const LL b,LL &x,LL &y)
{  if(!b){x=1,y=0;return a;  }const LL res=EXgcd(b,a%b,y,x);y-=a/b*x;return res;
}
inline LL msc(LL a,LL b,LL mod)
{LL v=(a*b-(LL)((long double)a/mod*b+1e-8)*mod);return v<0?v+mod:v;
}
int n,a[11],p[11];
LL CRT()
{  LL P=1,sum=0;  for(rg int i=1;i<=n;i++)P*=p[i];for(rg int i=1;i<=n;i++)  {const LL m=P/p[i];LL x,y;EXgcd(p[i],m,x,y);sum=(sum+msc(msc(y,m,P),a[i],P))%P;}return sum;
}
int main()
{read(n);for(rg int i=1;i<=n;i++)read(a[i]);for(rg int i=1;i<=n;i++){read(p[i]);a[i]=(a[i]%p[i]+p[i])%p[i]; }print(CRT());return flush(),0;
}

扩展中国剩余定理(exCRT)

问题

给出nnn个同余方程
x≡a1(modp1)x≡a2(modp2)⋅⋅⋅⋅⋅⋅⋅⋅x≡an(modpn)\begin{aligned} x&amp;\equiv a_1\pmod{p_1}\\ x&amp;\equiv a_2\pmod{p_2}\\ ··&amp;\ \ \ \ \ ···\ \ \ \ \ \ \ \ ···\\ x&amp;\equiv a_n\pmod{p_n}\\ \end{aligned} xx⋅⋅x​≡a1​(modp1​)≡a2​(modp2​)     ⋅⋅⋅        ⋅⋅⋅≡an​(modpn​)​
求最小自然数解xxx
(与上面的问题的不同在于这里不保证所有的ppp两两互质)

做法

考虑我们现在已经符合了前k−1k-1k−1个限制了
设P=lcm(p1,p2⋅⋅⋅pk−1)P=lcm(p_1,p_2···p_k-1)P=lcm(p1​,p2​⋅⋅⋅pk​−1),容易发现,满足前k−1k-1k−1个限制的最小的自然数x&lt;Px&lt;Px<P
证明同理,也就是现在答案是x+tPx+tPx+tP形式的
我们要满足第kkk个限制,其实很方便,就是找到一个ttt满足
x+tP≡ak(modpk)x+tP\equiv a_k\pmod{p_k}x+tP≡ak​(modpk​)
移项tP≡ak−x(modpk)tP\equiv a_k-x\pmod{p_k}tP≡ak​−x(modpk​)
转化tP+qpk≡ak−xtP+qp_k\equiv a_k-xtP+qpk​≡ak​−x
然后直接拓展欧几里得求解
若无解输出无解
否则直接将答案更新

例题

洛谷P4777 【模板】扩展中国剩余定理(EXCRT)
这道题保证有解,所以不用判无解了,保证了解的范围,所以容易发现不用高精度

代码

贴出ac代码,代码里有句注释,是用来判无解的
为了卡常才把它注释掉的

#include<cstdio>
#include<cctype>
#include<algorithm>
namespace fast_IO
{const int IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inline char getchar_(){return (ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inline void putchar_(const char x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
}
using namespace fast_IO;
#define getchar() getchar_()
#define putchar(x) putchar_((x))
#define rg register
typedef long long LL;
template <typename T> inline T max(const T a,const T b){return a>b?a:b;}
template <typename T> inline T min(const T a,const T b){return a<b?a:b;}
template <typename T> inline void mind(T&a,const T b){a=a<b?a:b;}
template <typename T> inline void maxd(T&a,const T b){a=a>b?a:b;}
template <typename T> inline T abs(const T a){return a>0?a:-a;}
template <typename T> inline void swap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T> inline T gcd(const T a,const T b){if(!b)return a;return gcd(b,a%b);}
template <typename T> inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T> inline T square(const T x){return x*x;};
template <typename T> inline void read(T&x)
{char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;
}
template <typename T> inline void printe(const T x)
{if(x>=10)printe(x/10);putchar(x%10+'0');
}
template <typename T> inline void print(const T x)
{if(x<0)putchar('-'),printe(-x);else printe(x);
}
LL EXgcd(const LL a,const LL b,LL &x,LL &y)
{  if(!b){x=1,y=0;return a;  }const LL res=EXgcd(b,a%b,y,x);y-=a/b*x;return res;
}
inline LL msc(LL a,LL b,LL mod)
{LL v=(a*b-(LL)((long double)a/mod*b+1e-8)*mod);return v<0?v+mod:v;
}
LL n,a[100001],p[100001];
LL EXCRT()
{  LL P=1,sum=0;  for(rg int i=1;i<=n;i++)  {const LL o=((a[i]-sum)%p[i]+p[i])%p[i];//if(o%gcd(P,p[i])!=0)return -1;const LL xs=o/gcd(P,p[i]);LL x,y;EXgcd(p[i],P,x,y);const LL M=P;P=P/gcd(P,p[i])*p[i];sum=(sum+msc(msc(y,M,P),xs,P))%P;}return sum;
}int main()
{read(n);for(rg int i=1;i<=n;i++){read(p[i]),read(a[i]);a[i]=(a[i]%p[i]+p[i])%p[i];}print(EXCRT());return flush(),0;
}

总结

并不是很难的两个算法,学起来很方便
后记:感觉exCRT严格优于CRT,有没有大佬指出CRT有什么用啊

中国剩余定理(CRT)扩展中国剩余定理(exCRT)相关推荐

  1. [数论]-----中国剩余定理(扩展中国剩余定理)

    中国剩余定理 中国剩余定理(CRT)用于求形如: { x ≡ a 1 ( m o d m 1 ) x ≡ a 2 ( m o d m 2 ) ⋯ ⋯ x ≡ a k ( m o d m k ) \be ...

  2. 中国剩余定理(CRT)和扩展中国剩余定理(EXCRT)

    Tip:建议读者不要太着急后翻,按照顺序阅读有助于理解 中国剩余定理(CRT) 问题引出 "有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二.问物几何?"即,一个整数除以三余 ...

  3. 中国剩余定理(CRT)及其扩展(EXCRT)详解

    博客园食用效果更佳 目录 问题背景 扩展欧几里得算法 有啥用呢: 裴蜀等式: 裴蜀等式求解过程: 同余方程求解过程: C R T \mathrm{CRT} CRT 问题的解决方法 构造出解 逆元求法 ...

  4. 中国剩余定理及扩展中国剩余定理

    目录 中国剩余定理CRT 扩展中国剩余定理ExCRT TJOI2009 猜数字 HDU 1573 X问题 中国剩余定理CRT 中国剩余定理是用来求线性同于方程组的. \[ \begin{aligned ...

  5. 中国剩余定理 扩展中国剩余定理 模板

    中国剩余定理解线性同余线性方程 /*long long gcd(LL a,LL b) {return b==0?a:gcd(b,a%b); }*/ #include<bits/stdc++.h& ...

  6. 数学--数论--中国剩余定理+扩展中国剩余定理(孙子定理)

    中国剩余定理 问题 求解同余方程组 其中m1,m2,m3...mkm_1,m_2,m_3...m_km1​,m2​,m3​...mk​为两两互质的整数 求x的最小非负整数解 定理 令M=∏i=1kmi ...

  7. 中国剩余定理以及扩展中国剩余定理

    中国剩余定理必须有两两互质的条件:而扩展中国剩余定理没有限制(可能互质,也能不互质).所以只记忆一个扩展中国剩余定理的板子就行. 代码 #include <iostream> #inclu ...

  8. 中国剩余定理 扩展中国剩余定理 (模板)

    中国剩余定理 && 扩展中国剩余定理 一个整数除以三余二,除以五余三,除以七余二,求这个整数. 例题: 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % ...

  9. 数论——中国剩余定理及其扩展详解

    文章目录 概述 中国剩余定理扩展 例题 总结 概述 引入: 一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作<孙子算经>卷下第二十六题,叫做"物不知数&qu ...

最新文章

  1. DatagridView自动充满屏幕,并能指定某列宽度
  2. matlab极大值点个数,求一组数的极大值个数
  3. SDO_GEOMETRY Object Type
  4. 高频面试题1:自增边量
  5. 漫步微积分二十四——定积分引言
  6. CentOS 6.5 x64安装svn
  7. Use the onReadyStateChange Property (Visual Basic)
  8. 算法之路 level 01 problem set
  9. 关于面向对象和面向过程等小例子(持续更新)
  10. GIMP 基本教程(1)
  11. 射频识别技术漫谈(17)——射频卡中数据的存储形式
  12. 迷你上标和下标复制大全(含0~9、字母、特殊字符)
  13. Windows安全描述符SECURITY_DESCRIPTOR阅读注释
  14. 通带纹波、阻带纹波、通带最大波纹和阻带最小衰减
  15. 【基于stm32 FreeRtos的智能台灯控制】
  16. java.lang.NoSuchMethodError的解决办法
  17. html5 表格 在线生成,专业的Web报表软件——在线表格生成制作工具
  18. Win10插入耳机无反应
  19. CentOS 7安装配置vsftp并搭建FTP(一)
  20. 软件著作权-源码清理

热门文章

  1. 用户关联角色操作-流程分析
  2. 禁用Zuul的过滤器
  3. 单点登录Redis存储Session及SessionId问题说明与集群实战-4
  4. 设计模式之_动态代理_05
  5. Bootstrap全局css样式_代码
  6. SpringBoot Bean配置
  7. 200820C阶段一通用链表
  8. 转 执行计划突变分析
  9. Push rejected: Push to origin/master was rejected
  10. PostgreSQL 10.1 手册_部分 II. SQL 语言_第 9 章 函数和操作符_9.18. 数组函数和操作符...