数论 —— 线性同余方程组与中国剩余定理
【线性同余方程组】
由若干个线性同余方程构成的线性方程组。
例如:
其解法最早由我国《孙子算经》给出,因此解法称为“孙子定理”,又叫“中国剩余定理”,实质即为求多个数的最小公倍数。
【中国剩余定理】
1.内容
设自然数 两两互质,并记
,则同余方程组:
在模 N 同余的意义下,有唯一解:
。
2.证明
考虑方程组:,
由于 两两互质,对方程组作变量替换,即令
故方程组等价于解同余方程:
若想得到特解
只要令 即可
故方程组的解为:,在模 N 下值唯一。
3.应用
中国剩余定理就是用来求线性同余方程组的,即对方程组:,在 W、B 的值已知,且 W[i]>0,W[i] 与 W[j] 互质,求 a 的值。
4.实现
#include<iostream>
using namespace std;
int Extended_GCD(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int gcd=Extended_GCD(b,a%b,y,x);
y=y-a/b*x;
return gcd;
}
int China(int W[],int B[],int k){//W除数,B余数
int mod=1;
for(int i=0;i<k;i++)//计算mod的大小
mod*=W[i];
int res=0;
int x,y,m;
for(int i=0;i<k;i++){
m=mod/W[i];
Extended_GCD(W[i],m,x,y);//求出每一组W[i]与m的解
res=(res+y*B[i]*mod/W[i]+mod)%mod;//累加所有解
}
return (res+mod)%mod;
}
【不互素的中国剩余定理】
对于不互素的中国剩余定理, 即:a[1],a[2],.....,a[n],不互素的情况,只能每两个一组的求解,有:
设:k1、k2 ,易得:
即:
对整个式子进行 a2 取余,得:
此时式子只有一个未知量 k1,使用扩展欧几里得定理可求出 k1,从而计算出:
这个 x 仅是满足 的一个特解,不一定是
的解,因此要想求出式子真正的解,需要取 x 对 a1、a2 最小公倍数的模
即:
由于只有 ans 是未知数,因此就将两个式子转换为一个式子,通过这样不断的合并,可以求出最终的结果。
判断是否有解,在扩展欧几里得中求 k1 时判断即可。
int Extended_GCD(int a,int b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
LL gcd=Extended_GCD(b,a%b,y,x);
y=y-a/b*x;
return gcd;
}
int GCD(int a,int b){
return b==0?a:GCD(b,a%b);
}
int CRT(int W[],int B[],int n)//w为除数,b为余数,n为有多少式子
{
int res=B[0],Wi=W[0];
for(int i=1;i<n;i++)
{
int bi=B[i],wi=W[i];
int x,y;
int gcd=Extended_GCD(Wi,wi,x,y);
int c=bi-res;
if(c%gcd!=0)//表示没有结果
return -1;
int M=wi/gcd;
res+=Wi*( ((c/gcd*x)%M+M) % M);
Wi*=M;
}
if(res==0)//除数全为0
{
res=1;
for(int i=0;i<n;i++)
res=res*W[i]/GCD(res,(LL)W[i]);
}
return res;
}
int a[N],b[N];
int main(){
int k;
while(scanf("%d",&k)!=EOF&&k){
for(LL i=0;i<k;i++)
scanf("%d%d",&a[i],&b[i]);//先除数后余数
printf("%d\n",CRT(a,b,k));
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探