中国剩余定理 学习笔记
前言:先食用同余,会有更好的学习效果。
--------------------
中国剩余定理:若$m_{1},m_{2}...m_{n}$是两两互质的正整数,$M=\prod_{i=1}^{n} m_{i},M_{i}=M/M_{i}$,$t_{i}$是线性同余方程$M_{i}t_{i}\equiv 1(mod m_{i})$的一个解。对于任意的$n$个整数$a_{1},a_{2}...a_{n}$,则同余方程组:
$x\equiv a_{1}(mod m_{1})$
$x\equiv a_{2}(mod m_{2})$
$\cdots$
$x\equiv a_{n}(mod m_{n})$
有整数解,方程组的解为$x=a_{1}M_{1}t_{1}+a_{2}M_{2}t_{2}+...+a_{n}M_{n}t_{n}$。并且在模$M$的意义下有唯一解。
证明:
因为$M_{i}=M/m_{i}$是除$m_{i}$之外所有模数的倍数,所以对于任意$k\ne i$,$a_{i}M_{i}t_{i}\equiv 0(mod m_{i})$。又因为$a_{i}M_{i}t_{i}\equiv a_{i}(mod m_{i})$(由定义得),所以$x=\sum_{i=1}^{n}a_{i}M_{i}t_{i}$,原方程组成立。
--------------------
【模板】曹冲称象
代码:
#include<bits/stdc++.h> using namespace std; typedef long long LL; LL a[11],b[11],N,M=1,Ans=0; void Read() { cin>>N; for (LL i=1;i<=N;i++) { cin>>a[i]>>b[i]; M*=a[i]; } } void exgcd(LL a,LL b,LL &d,LL &x,LL &y) { if (!b){x=1;y=0;d=a;} else{ exgcd(b,a%b,d,x,y); LL t=x;x=y;y=t-a/b*y; } } void intchina() { LL Mi,x,y,i,d; for (i=1;i<=N;i++) { Mi=M/a[i]; exgcd(Mi,a[i],d,x,y); Ans=((Ans+Mi*x*b[i])%M+M)%M; } cout<<Ans<<endl; } int main() { Read(); intchina(); return 0; }