这个定理有两个版本,下面是互质版(非扩展版)的代码,具体讲解可以参考信息学竞赛数学一本通。做法大概就是:
把一个同余方程组:
x≡b1(mod m1)
x≡b2(mod m2)
x≡b3(mod m3)
……
x≡bn(mod mn)
转化成n个同余方程组:
x≡0(mod m1)
x≡0(mod m2)
……
x≡1(mod mi)
……
x≡0(mod mn)
每组解出来乘上对应mi加起来即可(每加一次都要模M,M=m1xm2x……xmn)
还可以去看看下面一篇博客:
CRT证明
FZU 1402是一道模板题,可以在vjudge上找到,代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
ll b[12],m[12];
ll exgcd(ll a,ll b,ll &x,ll &y) {
if (!b) {
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return d;
}
ll crt() {
ll mult=1,x,y,t,a=0;
for (int i=1;i<=n;i++) mult*=m[i];
for (int i=1;i<=n;i++) {
t=mult/m[i];
ll d=exgcd(m[i],t,x,y);
y=(y%m[i]+m[i])%m[i];
a=(a+y*t*b[i])%mult;
}
return (a%mult+mult)%mult;
}
int main() {
while (~scanf("%d",&n)) {
for (int i=1;i<=n;++i) scanf("%I64d%I64d",&m[i],&b[i]);
printf("%I64d\n",crt());
}
return 0;
}