P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪 讲解
首先它是用来求以下方程组的解的:
注:对于任意的
那么怎么解呢?
我们定义
那么最后解的形式就是:
答案可不可行呢?我们就拿
其余同理。(啥?你说你不会扩欧?)
扩欧适用于解决类似以下方程的:
怎么解决呢?
考虑以下式子是否成立:
它是成立的,因为
然后我们一直向下,直到
解得
那么,我们能否用这一次的解推出上一次的解呢?
我们对其进行拆分:
与
根据以上内容,易得代码:
#include<bits/stdc++.h>
#define int long long
#define inl inline
#define INF 214748364721474836
#define rep(i,x,y) for(int i=x;i<=y;++i)
using namespace std;
inl int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f*x;
}
inl void write(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>=10) write(x/10);
putchar(x%10^48);
return;
}
int n,a[15],m[15],num=1,M[15],N[15],ans1,ans2,sum;
inl void exgcd(int a,int b){
if(!b){
ans1=1;
ans2=0;
return;
}
exgcd(b,a%b);
int copyans=ans1;
ans1=ans2;
ans2=copyans-a/b*ans2;
}
signed main(){
n=read();
rep(i,1,n){
m[i]=read();
num*=m[i];
a[i]=read();
}
rep(i,1,n) M[i]=num/m[i];
rep(i,1,n){
exgcd(M[i],m[i]);
N[i]=ans1;
}
rep(i,1,n) sum+=M[i]*N[i]*a[i];
write((sum%num+num)%num);
return 0;
}