中国剩余定理
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
中国的古人在很早的时候就发现了此题的解法:
三人同行七十稀,五树梅花廿一枝,七子团圆正半月,除百零五便得知。
具体操作流程此处不过多赘述。
这个被叫做“物不知数”的问题本质上是解下面的同余方程组:
这一方程组有解的一个充分条件是
回到刚才的原问题:找到
找到一个
那么直接令
显然不行
那么令
这样推下去,
注意到模数两两互质,则
解得
接下来不妨将上述过程公式化
我们设
我们把以上这些综合成一个公式即是 :
代码实现
【模板】中国剩余定理(CRT)
一.
int a[N],b[N];
unsigned int M = 1 , t[N] , ans;
signed main(){
int n = read();
for(int i=1;i<=n;i++){
a[i] = read() , b[i] = read();
M *= a[i];
}
for(int i=1;i<=n;i++){
t[i] = M/a[i];
}
for(int i=1;i<=n;i++){
for(unsigned int j=t[i];j<=0x7f7f7f7f7f7f;j+=t[i]){
if(j % a[i] == 1){
ans += j * b[i] % M;
break;
}
}
}
printf("%lld\n",ans % M);
return 0;
}
二.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
const int N = 55;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(; isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
int n,a[N],b[N],M=1;
inline void exgcd(int a,int b,int &x,int &y){
if(b == 0){
x=1;y=0;
}
else{
exgcd(b,a%b,x,y);
int t = x;
x = y;
y = t-(a/b)*y;
}
}
inline int CRT(){
int ans = 0,T,x,y;
for(int i=1;i<=n;++i){
T = M / a[i];
exgcd(T,a[i],x,y);
ans = ((ans + T * x * b[i]) % M + M) % M;
}
return (ans + M) % M;
}
signed main(){
n = read();
for(int i=1;i<=n;++i){
a[i] = read() , b[i] = read();
M *= a[i];
}
printf("%lld\n",CRT());
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】