『数论·同余』中国剩余定理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ronaldo7_ZYB/article/details/89321244

中国剩余定理问题

中国剩余定理,就是给定 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n ,以及 m 1 , m 2 , . . . , m n m_1,m_2,...,m_n ,求一个给定的 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

中国剩余定理结论

N   = i = 1 n m i    ,    M i   =   N m i N\ =\prod_{i=1}^{n}m_i\ \ ,\ \ M_i\ =\ \frac{N}{m_i} .并满足 M i t i     a i ( m o d   m i ) M_i*t_i\ \equiv\ a_i(mod\ m_i)

则我们做求的 x   =   i = 1 n a i t i M i x\ =\ \sum_{i=1}^{n}a_it_iM_i .

中国剩余定理证明

对于任意 a i t i M i a_it_iM_i 来说,一定满足:

  • 1. a i t i M i   ̸   0 ( j   = ̸   i ) a_it_iM_i\ \equiv\not\ 0(j\ =\not\ 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)

第一个条件保证了 i i 不对其他产生影响;第二个条件保证了一定满族问题中的同余条件。

中国剩余定理的实现

M i t i     a i ( m o d   m i ) M_i*t_i\ \equiv\ a_i(mod\ m_i) 中,求解 t i t_i 需要用到扩展欧几里得求解线性同余方程的算法;剩下的都很好实现了吧。注意一般题目里数值都比较大,需要开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;
}

猜你喜欢

转载自blog.csdn.net/Ronaldo7_ZYB/article/details/89321244
今日推荐