中国剩余定理问题
中国剩余定理,就是给定 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an,以及 m 1 , m 2 , . . . , m n m_1,m_2,...,m_n m1,m2,...,mn,求一个给定的 x x x满足:
- a i ≡ x ( m o d m i ) , 1 ≤ i ≤ n a_i\ \equiv\ x(mod\ m_i),\ \ \ 1\leq i\leq n ai ≡ x(mod mi), 1≤i≤n
中国剩余定理结论
设 N = ∏ i = 1 n m i , M i = N m i N\ =\prod_{i=1}^{n}m_i\ \ ,\ \ M_i\ =\ \frac{N}{m_i} N =∏i=1nmi , Mi = miN.并满足 M i ∗ t i ≡ a i ( m o d m i ) M_i*t_i\ \equiv\ a_i(mod\ m_i) Mi∗ti ≡ ai(mod mi)。
则我们做求的 x = ∑ i = 1 n a i t i M i x\ =\ \sum_{i=1}^{n}a_it_iM_i x = ∑i=1naitiMi.
中国剩余定理证明
对于任意 a i t i M i a_it_iM_i aitiMi来说,一定满足:
- 1. a i t i M i ≡ ̸ 0 ( j = ̸ i ) a_it_iM_i\ \equiv\not\ 0(j\ =\not\ i) aitiMi ≢ 0(j ≠ i)
- 2. a i t i M i ≡ a i ( m o d m i ) a_it_iM_i\ \equiv\ a_i(mod\ m_i) aitiMi ≡ ai(mod mi)
第一个条件保证了 i i i不对其他产生影响;第二个条件保证了一定满族问题中的同余条件。
中国剩余定理的实现
M i ∗ t i ≡ a i ( m o d m i ) M_i*t_i\ \equiv\ a_i(mod\ m_i) Mi∗ti ≡ ai(mod mi)中,求解 t i t_i ti需要用到扩展欧几里得求解线性同余方程的算法;剩下的都很好实现了吧。注意一般题目里数值都比较大,需要开longlong。
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const LL S = 50;
int n;
LL x,y;
LL m[S],a[S];
LL Exgcd(LL a,LL b,LL c)
{
if (b == 0)
{
x = c/a;
y = 0;
return a;
}
LL t = Exgcd(b,a%b,c);
LL X = x,Y = y;
x = Y;
y = X-a/b*Y;
return t;
}
int main(void)
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
LL N = 1,ans = 0;
cin>>n;
for (int i=1;i<=n;++i)
{
cin>>m[i]>>a[i];
N = N*m[i];
}
for (int i=1;i<=n;++i)
{
Exgcd(N/m[i],m[i],1);
ans = ans+x*N/m[i]*a[i];
}
cout<<(ans%N+N)%N<<endl;
return 0;
}