中国剩余定理
描述
问题描述
回到梦开始的地方:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?
不过评测寄可读不懂古文,我们给出形式化的问题描述:
给定下列线性同余方程组:
两两互素。
求解 。
定理描述
令
令 表示 的乘法逆元。
则其通解的形式为:
证明
显然地,由于 互素,则 与 互素。
这说明 在模 意义下乘法逆元必存在。
自然地:
显然地:
所以 。
故 为一个合法解。
若另一合法解为
而 互素,这说明 ,故方程任意两解间必相差 的整数倍,定理得证。
当 ,。
代码实现
实现难度不高,要注意的是乘法逆元在不同题目中的处理方式,对于洛谷模板,我们用 求解(模数互素)。
namespace CRT {
const int N = 10004;
int n;
typedef long long vType;
vType r[N], m[N], M;
void init(int _n, int *_r, int *_m) {
n = _n;
m = 1;
for (int i=1; i<=n; i++) {
m[i] = _m[i];
r[i] = _r[i];
M *= m[i];
}
}
void exgcd(vType a, vType b, vType &x, vType &y) {
if (!b) {
x=1;y=0;
return ;
}
vType xx, yy;
exgcd(y, x%y, xx, yy);
x = yy;
y = xx - (a/b)*yy;
}
vType solve() {
vType ans = 0;
for (int i=1; i<=n; i++) {
vType p=M/r[i], q, tmp;
exgcd(p,m[i],q,tmp);
if (q<0) q += M;
ans = (ans + ((p*q)%M*r[i])%M)%M;
}
ans %= M;
if (ans < 0) ans += M;
return ans;
}
}
本来想在 exgcd 那里夹带私货的
后记
上次在知乎上看到了一篇优美的抽象代数证明,不过菜狗不会,有机会再补。