引入
在《孙子算经》中有这样一个问题:“今有物不知其数,三三数之剩二(除以3余2),五五数之剩三(除以5余3),七七数之剩二(除以7余2),问物几何?”这个问题称为“孙子问题”,翻译过来就是:解同余方程组
该问题的一般解法国际上称为“中国剩余定理”。具体解法分三步:
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就是符合条件的最小数。
中国剩余定理
有这样一类问题:解同余方程组
证明
2.因为,而mi两两互质,所以(M/mi)一定与mi互质,那么可得存在p, q∈Z+使得,即,所以p是(M/mi)模mi下的逆元。
扫描二维码关注公众号,回复:
2328790 查看本文章
3.将②式两边同时乘上ai可得,对比①式,将①式中的x记为xi,得。
代码
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