中国剩余定理 学习总结
中国剩余定理
前置芝士
同余方程
问题
现给定一个方程组:\(\begin{cases}x\equiv a_1(mod\ m_1)\\x\equiv a_2(mod\ m_2)\\ \cdots \cdots\\x\equiv a_n(mod\ m_n)\\\end{cases}\),需要求出\(x\)的值
分析
来举个简单的例子:
\[\begin{cases}x\equiv 2(mod\ 3)\\x\equiv 3(mod\ 5)\\x\equiv 2(mod\ 7)\\\end{cases}
\]
我们用递推的思想把一个大问题转化为小问题。先求出以下三个方程组的解。
\[\begin{cases}x\equiv 1(mod\ 3)\\x\equiv 0(mod\ 5)\\x\equiv 0(mod\ 7)\\\end{cases},\begin{cases}x\equiv 0(mod\ 3)\\x\equiv 1(mod\ 5)\\x\equiv 0(mod\ 7)\\\end{cases},\begin{cases}x\equiv 0(mod\ 3)\\x\equiv 0(mod\ 5)\\x\equiv 1(mod\ 7)\\\end{cases}
\]
举第一个方程的例子,可以转化为\(35y\equiv 1(mod\ 3)\)。
这时候,我们可以把方程组转化为同余方程来做。
而最先的那个方程组就可以用这些答案来表示。
我们用\(\begin{bmatrix}2\\3\\2 \end{bmatrix}\)来表示\(\begin{cases}x\equiv 2(mod\ 3)\\x\equiv 3(mod\ 5)\\x\equiv 2(mod\ 7)\\\end{cases}\),则最后可以写成这样:
\[\begin{bmatrix}2\\3\\2 \end{bmatrix}=2\begin{bmatrix}1\\0\\0\end{bmatrix}+3\begin{bmatrix}0\\1\\0 \end{bmatrix}+2\begin{bmatrix}0\\0\\1 \end{bmatrix}
\]
这样,代码的实现就很显然了。
代码
#include <bits/stdc++.h>
#define ll long long
#define re register int
const int INF=1<<30;
const int mod=1e9+3;
using namespace std;
template <typename T>
inline void read(T &x) {
x = 0;
ll f = 1;
char ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') f = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + (ch ^ 48);
ch = getchar();
}
x *= f;
return;
}
template <typename T>
inline void write(T x){
if(x < 0) {
putchar('-');
x = -x;
}
if(x > 9)
write(x/10);
putchar(x % 10 + '0');
return;
}
ll n,a[15],b[15],M=1,res;
inline ll exgcd(ll a,ll b,ll &x,ll &y) {
if(!b) {
x=1;y=0;
return a;
}
ll q=exgcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
int main() {
read(n);
for(int i=1;i<=n;i++)
read(a[i]),read(b[i]);
for(re i=1;i<=n;i++)
M*=a[i];
for(re i=1;i<=n;i++) {
ll m,p,d,y;
m=M/a[i];
d=exgcd(m,a[i],p,y);
res=(res+m*p*b[i])%M;
}
if(res<0) res+=M;
write(res);
}

浙公网安备 33010602011771号