前言
中国剩余定理也要学好的哈,共勉!!!
一、中国剩余定理的介绍
中国剩余定理释义:又称“孙子定理”。1852年,英国来华传教士伟烈亚力将《孙子算经》中“物不知数”问题的解法传至欧洲。1874年,英国数学家马西森指出此法符合1801年由高斯得出的关于同余式解法的一般性定理,因而西方称之为“中国剩余定理”。
孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
二、例题及模板
表达整数的奇怪方式:
AC代码:
// P1495 中国剩余定理
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
using LL = long long ;
LL a[N], m[N], M = 1;
int n;
LL exgcd(LL a, LL b, LL &x, LL &y) {
if (!b) {
x = 1, y = 0;
return a;
}
LL d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
// 中国剩余定理的模板
LL CRT() {
LL ans = 0;
for (int i = 1; i <= n; i ++ ) {
LL Mi = M / m[i];
LL x, y;
exgcd(Mi, m[i], x, y); // 利用扩展欧几里得求出x和y
// 此时的x就是Mi模mi意义下的逆元
ans = ((ans + a[i] * Mi * x) % M + M) % M; // 保证最小正整数解
}
// 这里也可以写成reutnr ans 因为上面已经保证求出来的ans是最小正整数解了
return (ans % M + M) % M; // 保证最小正整数解
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) {
// 这里m[i]就是题目中猪圈数,a[i]就是无家可归的猪数
scanf("%lld%lld", &m[i], &a[i]);
M *= m[i]; // 累乘每个式子中模数mi 得到M
}
printf("%lld\n", CRT());
return 0;
}