中国剩余定理
Chivas-Regal
# 导引问题
求出一个x满足多个模线性方程
例如:
# 经典问题 ———— 物不知数
“今有物,不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?” ————《孙子算经》
等价于求下面这个模线性方程组的正整数解
问题分析:
1.特殊的线性同余方程组
(特殊点:模数两两互质)
2.中国剩余定理(孙子定理)
# 定义
若是两两互质的正整数,则对于任意的n个整数,同余方程组 有正整数解,并且在模M下解唯一
构造方程组的解为:
其中: 是线性同余方程
的一个解(因为 和 互质,必有解)
问题转化:求n个线性同余方程的公共解
int ChineseRemain(int n){
int Ans = 0, M = 1;
for (int i = 1; i <= n; i ++) M *= m[i];
for (int i = 1, Mi, xi, yi, d; i <= n; i ++){
Mi = M / m[i];
d = exgcd(Mi, m[i], xi, yi);
Ans = (Ans + Mi * xi * a[i]) % M;
}
return (Ans + M) % M;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 回顾经典 ———— 物不知数
问题的通解是:
# 一般情况
模数 不保证两两互质,即进入到"中国剩余定理的一般情况"
- 数学归纳法
- 假设已经求出前k-1个方程构成的方程组的一个解x
记 , 则 是前 个方程的通解
此时 依然是前 个方程的解是因为在对m取模的情况下,加m的倍数得到的结果不变 - 同样的,考虑第k个方程,求出一个合理的倍数t使得其成为第k个方程的解,即
该方程等价于 ,其中t是未知量。 - 可以判断是否有解,若有解,则可以用扩欧求出这个解。也就是说, 就是前k个方程构成的方程组的一个解。
若无解,总方程无解。
inline ll Ex_crt(){
ll X = a[1], M = m[1]; //前一步的X,前一步的lcm
for (ll i = 2, t, y; i <= n; i ++){
ll gcd = Ex_gcd(M, m[i], t, y), miDIVgcd = m[i] / gcd; // 求得gcd,并使m[i]约分一下好乘进M里面
ll c = (a[i] - X % m[i] + m[i]) % m[i];//ax≡c(mod b) 等式右侧的c,并让他变成可行的最小正整数
if(c % gcd) return -1;
t = ksc(t, c / gcd, miDIVgcd); // 因为扩欧求得的是等号右侧为gcd时的x解,而此时等号右端为c,需要让X乘上c/gcd个t,此时先给t变了再说
X += t * M;
M *= miDIVgcd; //计算LCM
X = (X % M + M) % M; //保持最小正整数解
}return X;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14