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

中国剩余定理问题

中国剩余定理,就是给定 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),   1in

中国剩余定理结论

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) Miti  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) Miti  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;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值