同余问题常用定理证明
扩展欧几里得算法
扩展欧几里得定理:设 \(a\) 和 \(b\) 不全为 \(0\),则存在整数 \(x\) 和 \(y\),使得 \(ax + by = (a, b)\)。
证明:设 \(d = (a, b)\),求 \(ax + by = d\) 的一组 \((x, y)\)。
欧几里得算法可知,\(bx ^ {\prime} + (a \bmod b) y ^ {\prime} = d\)。
即 \(bx ^ {\prime} + (a - \lfloor \frac{a}{b} \rfloor \cdot b) y ^ {\prime} = d\),\(ay ^ {\prime} + b(x ^ {\prime} - \lfloor \frac {a}{b} \rfloor \cdot y ^ {\prime}) = d\)。
则 \(x = y ^ {\prime}, y = x ^ {\prime} - \lfloor \frac {a} {b} \rfloor \cdot y ^ {\prime}\)。
可以通过欧几里得算法递归迭代到 \(a ^ {\prime} = d, b ^ {\prime} = 0\) 时可以得到此时 \(x ^ {\prime} = 1, y ^ {\prime} = 0\),再利用上面推出的 \(x, y\) 与 \(x ^ {\prime}, y ^ {\prime}\) 的关系进一步代入计算,得到 \(ax + by = (a, b)\) 的一组解。
利用归纳法,最后解的大小满足:\(|x| \leq b, |y| \leq a\)。
int exgcd (int a, int b, int &x, int &y) {
if (!b) {
x = 1, y = 0;
return a;
}
int d = exgcd (b, a % b, y, x);
y -= (a / b) * x;
return d;
}
欧拉定理 & 费马小定理
欧拉定理:若 \((a, m) = 1\),则 \(a ^ {\varphi (m)} \equiv 1 \pmod{m}\)。
证明:设 \(r_{1}, r_{2}, \cdots , r_{\varphi (m)}\) 是模 \(m\) 的缩系,因为 \((a, m) = 1\),所以 \(ar_{1}, ar_{2}, \cdots,r_{\varphi}\) 也是模 \(m\) 的缩系。
即 \(r_{1}r_{2} \cdots r_{\varphi(m)} \equiv ar_{1} \cdot ar_{2} \cdots ar_{\varphi(m)} \equiv a ^ {\varphi (m)}r_{1}r_{2} \cdots r_{\varphi (m)}\)。
根据缩系性质,可约去 \(r_{1}r_{2} \cdots r_{\varphi (m)}\),即得 \(a ^ {\varphi (m)} \equiv 1 \pmod {m}\)。
费马小定理:若 \(p\) 为素数,则 \(a ^ {p - 1} \equiv 1 \pmod {p}\)。
证明:当 \(p\) 为素数 \((a, p) = 1\),由于 \(\varphi (m - 1) = m - 1\),带入欧拉定理可立即得到费马小定理。
线性同余方程
设 \((a, m) = d\),则一次同余方程:\(ax \equiv b \pmod {m}\),有解的充要条件是 \(d \mid b\)。
设同余方程有解 \(x = c\),则 \(m \mid (ac - b)\),从而 \(d \mid (ac - b)\),但 \(d \mid a\),故 \(d \mid b\)。
反过来,若 \(d \mid b\),则同余方程与 \(\frac {a}{d} x \equiv \frac {b}{d} \pmod {\frac {m}{d}}\) 同解,任取模 \(\frac {m} {d}\) 的一个完系 \(c_{1}, \cdots, c_{\frac {m}{d}}\),因 \((\frac {a}{d}, \frac {m}{d}) = 1\),\(\frac {a}{d}c_{1} - \frac {b}{d}, \cdots, \frac {a}{d}c_{\frac {m}{d}} - \frac {b}{d}\) 也是模 \(\frac {m}{d}\) 的完系,所以同余方程存在整数解,且形成模 \(\frac {m}{d}\) 的一个同余类。但 \(d \mid b\) 时,原同余方程(模 \(m\))恰有 \(d\) 个解。
int x, y;
int d = exgcd (a, p, x, y);
if (b % d) {
res = -1;
} else {
x *= (b / d);
res = (x % (p / d) + (p / d)) % (p / d);
}
中国剩余定理
中国剩余定理:设 \(m_{1}, \cdots , m_{k}\) 是两两互素的正整数,则对于任意整数 \(b_{1}, \cdots ,b_{k}\),一次同余方程组 \(x \equiv b_{1} \pmod {m_{1}}, \cdots , x \equiv b_{k} \pmod {m_{k}}\) 必有解,且全部解是模 \(m_{1} \cdots m_{k}\) 的一个同余类。确切地说,同余方程组的解是 \(x \equiv M_{1}M_{1}^{-1}b_{1} + \cdots + M_{k}M_{k}^{-1}b_{k} \pmod {m_{1} \dots m_{k}}\)。
其中 \(M_{i}\) 及 \(M_{i}^{-1}\) \((1 \leq i \leq k)\) 由条件 \(m_{1} \cdots m_{k} \equiv M_{i}m_{i}, M_{i}M_{i}^{-1} \equiv 1 \pmod {m_{i}}\) 决定。因为 \((m_{i}, M_{i}) = 1\),故有整数 \(M_{i}^{-1}\),使得 \(M_{i}M_{i}^{-1} \equiv 1 \pmod {m_{i}}\)。对 \(j \neq i\),有 \(m_{j} \mid M_{i}\),因此数 \(d_{i} = M_{i}M_{i}^{-1}\),满足:\(d_{i} \equiv 1 \pmod {m_{i}}, d_{i} \equiv 0 \pmod {m_{j}}\) (对 \(j \neq i\))。
易于验证,上面的解的”叠加“ \(b_{1}d_{1} + \cdots + b_{k}d_{k}\) 满足同余方程组的解。
另一方面,如果 \(x, x^{\prime}\) 都是同余方程组的解,则 \(x \equiv x^{\prime} \pmod {m_{i}}, 1 \leq i \leq k\)。由 \(m_{1}, \cdots , m_{k}\) 两两互素知,\(x \equiv x^{\prime} \pmod {m_{1} \cdots m_{k}}\),因此同余方程组的解是模 \(m_{1} \cdots m_{k}\) 的一个同余类。
线性同余方程组
模数互质,使用中国剩余定理。
vector <int> A(n), B(n);
LL M = 1;
for (int i = 0; i < n; i ++ ) {
cin >> A[i] >> B[i];
M *= A[i];
}
LL res = 0;
for (int i = 0; i < n; i ++ ) {
LL Mi = M / A[i];
LL ti, x;
exgcd (Mi, A[i], ti, x);
res += B[i] * Mi * ti;
}
cout << (res % M + M) % M << "\n";
在模数不互质的情况下,设其中两个方程分别是 \(x \equiv a_{1} \pmod {m_{1}},x \equiv a_{2} \pmod {m_{2}}\)。转化为不定方程:\(x = m_{1}p + a_{1} = m_{2}q + a_{2}\),其中 \(p, q\) 是整数,则有 \(m_{1}p - m_{2}q = a_{2} - a_{2}\)。由裴蜀定理,当 \(a_{2} - a_{1}\) 不能被 \((m_{1}, m_{2})\) 整除时,无解;否则,扩展欧几里得定理得到一组可行解 \((p, q)\),则这两个方程组的解是 \(x \equiv b \pmod {M}\),其中 \(b = m_{1}p + a,M = [m_{1}, m_{2}]\)。多个方程两两合并。
LL res = 0, m1, a1;
cin >> m1 >> a1;
for (int i = 0; i < n - 1; i ++ ) {
LL m2, a2;
cin >> m2 >> a2;
LL k1, k2;
LL d = exgcd (m1, m2, k1, k2);
if ((a2 - a1) % d) {
res = -1;
}
k1 *= (a2 - a1) / d;
k1 = (k1 % (m2 / d) + (m2 / d)) % (m2 / d);
LL m = abs (m1 / d * m2);
a1 = k1 * m1 + a1;
m1 = m;
}
if (res != -1) {
res = (a1 % m1 + m1) % m1;
}
cout << res << "\n";

浙公网安备 33010602011771号