中国剩余定理(CRT)

引入

在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,翻译过来就是:解同余方程组

    image

该问题的一般解法国际上称为“中国剩余定理”。具体解法分三步:

1.找出三个数:从3和5的公倍数中找出被7除余1的最小数15,从3和7的公倍数中找出被5除余1 的最小数21,最后从5和7的公倍数中找出除3余1的最小数70。

2.用15乘以2(2为最终结果除以7的余数),用21乘以3(3为最终结果除以5的余数),同理,用70乘以2(2为最终结果除以3的余数),然后把三个乘积相加15∗2+21∗3+70∗2得到和233。

3.用233除以3,5,7三个数的最小公倍数105,得到余数23,即233%105=23这个余数23就是符合条件的最小数。

中国剩余定理

有这样一类问题:解同余方程组

image

image,则解为image,其中image是(M/mi)模mi下的逆元。

证明

1.对每一个image,有image

2.因为image,而mi两两互质,所以(M/mi)一定与mi互质,那么可得存在p, q∈Z+使得image,即image,所以p是(M/mi)模mi下的逆元。

扫描二维码关注公众号,回复: 2328790 查看本文章

3.将②式两边同时乘上ai可得image,对比①式,将①式中的x记为xi,得image

4.因为image,所以image,所以image。故整个方程组的解image。若是最小整数解,image

代码

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 using namespace std;
  5 
  6 typedef long long LL;
  7 LL a[1005], m[1005], M = 1, ans;
  8 int n;
  9 
 10 void ExGCD(LL a, LL b, LL &d, LL &x, LL &y)
 11 {
 12 	if(!b) d = a, x = 1, y = 0;
 13 	else
 14 	{
 15 		ExGCD(b, a % b, d, y, x);
 16 		y -= a / b * x;
 17 	}
 18 }
 19 LL Inverse(LL a, LL p)
 20 {
 21 	LL x, y, d;
 22 	ExGCD(a, p, d, x, y);
 23 	x = (x % p + p) % p;
 24 	return x;
 25 }
 26 int main()
 27 {
 28 	scanf("%d", &n);
 29 	for(int i = 0; i < n; i++)
 30 		scanf("%lld", a + i);
 31 	for(int i = 0; i < n; i++)
 32 	{
 33 		scanf("%lld", m + i);
 34 		M *= m[i];
 35 	}
 36 	for(int i = 0; i < n; i++)
 37 		ans = (ans + M / m[i] * Inverse(M / m[i], m[i]) % M * a[i] % M) % M;
 38 	ans = (ans + M) % M;
 39 	printf("%lld\n", ans);
 40 
 41 	return 0;
 42 }//Rhein_E 
View Code

猜你喜欢

转载自www.cnblogs.com/Rhein-E/p/9356696.html
今日推荐