中国剩余定理和扩展中国剩余定理
中国剩余定理
定理
且 , 是在模 意义下的乘法逆元
则有最小解
证明
简易说明
证明 是一个解
证明 是一个解以及最小解
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll maxn = 423;
ll int_maxn=1e9;
ll ll_maxn=1e18;
const ll mod=1e9+7;
const ll cs=998244353;
inline ll read_int(){
ll a=0,f=0,g=getchar();
while(g<'0'||g>'9'){if(g=='-') f=1;g=getchar();}
while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
return f ? -a : a;
}
inline void write(ll s,bool f){
int top=0,a[40];
if(s<0) s=-s,putchar('-');
while(s) a[++top]=s%10,s/=10;
if(top==0) a[++top]=0;
while(top) putchar(a[top]+'0'),top--;
if(f) putchar('\n');
}
ll n;
ll A[maxn],M[maxn];
ll T[maxn],MM[maxn];
ll lin=1;
inline ll exgcd(ll a,ll b,ll & x,ll & y){
if(b==0){x=1,y=0;return a;}
ll gcd=exgcd(b,a%b,y,x);
y-=a/b*x;
return gcd;
}
inline void read(){
n=read_int();
for(ll i=1;i<=n;i++) M[i]=read_int(),A[i]=read_int(),lin*=M[i];
for(ll i=1;i<=n;i++) MM[i]=lin/M[i];
ll ans=0;
ll x,y;
for(ll i=1;i<=n;i++) exgcd(MM[i],M[i],x,y),T[i]=(x%M[i]+M[i])%M[i];
for(ll i=1;i<=n;i++) ans=(ans+(A[i]*T[i]*MM[i]%lin+lin)%lin)%lin;
write(ans,1);
}
int main (){
read();
}
扩展中国剩余定理
说明:中国剩余定理和扩展中国剩余定理只有名字相似罢了,思路基本不同!!
求解方程
思路推导
由于不保证 互质,所以考虑将方程两个两个合并起来依次求解(可能无解)
注意:在写代码时,注意变量名
CODE
#include<bits/stdc++.h>
#define ll __int128
using namespace std;
const ll maxn = 423;
ll int_maxn=1e9;
ll ll_maxn=1e18;
const ll mod=1e9+7;
const ll cs=998244353;
inline ll read_int(){
ll a=0,f=0,g=getchar();
while(g<'0'||g>'9'){if(g=='-') f=1;g=getchar();}
while('0'<=g&&g<='9') a=a*10+g-'0',g=getchar();
return f ? -a : a;
}
inline void write(ll s,bool f){
ll top=0,a[40];
if(s<0) s=-s,putchar('-');
while(s) a[++top]=s%10,s/=10;
if(top==0) a[++top]=0;
while(top) putchar(a[top]+'0'),top--;
if(f) putchar('\n');
}
ll n;
ll a1,a2,m1,m2;
ll ans;
inline ll exgcd(ll a,ll b,ll& x,ll& y){
if(!b){x=1,y=0;return a;}
ll gcd=exgcd(b,a%b,y,x);
y-=a/b*x;
return gcd;
}
inline bool Extended_Chinese_remainder_theorem(){
ll x,y;
ll d=exgcd(m1,m2,x,y);
ll c=a2-a1;
if(c%d) return 0;
x=((c/d*x)%(m2/d)+m2/d)%(m2/d);
ll mod=m1/d*m2;
a1=((m1*x+a1)%mod+mod)%mod;
m1=mod;
return 1;
}
inline void read(){
n=read_int();
a1=read_int(),m1=read_int();
for(ll i=1;i<n;i++){
a2=read_int(),m2=read_int();
if(!Extended_Chinese_remainder_theorem()) {write(-1,0);return;}
}
write(a1%m1,1);
}
int main (){
read();
}
总结有以下毒瘤之处:
- 注意时刻保证 处于正确的范围之中
- 注意判断无解条件
- 多开
__int128
- 一定要熟练运用裴储定理以及同余性质!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】