中国剩余定理
\[ \nonumber \begin{cases} x&\equiv a_1\pmod{n_1}\\x&\equiv a_2\pmod{n_2}\\&\vdots\\x&\equiv a_k\pmod{n_k} \end{cases} \]
\[ \begin{gather} \nonumber m_i=\frac{n}{n_i}\\\nonumber c_i=m_i\cdot{m_i}^{-1}\pmod{n}\\\nonumber x=\sum_{i=1}^ka_i\cdot{c_i}\pmod{n} \end{gather} \]
模版
| C++ |
|---|
| void Exgcd(i64 a, i64 b, i64 &x, i64 &y) {
if (b == 0) {
x = 1;
y = 0;
return;
}
Exgcd(b, a % b, y, x);
y -= a / b * x;
}
i64 CRT(const vector<int> &a, const vector<int> &p) {
// p_i 两两互质
// ans % p_i = a_i
i64 n = 1, ans = 0;
int len = a.size();
for (int i = 0 ; i < len ; i++) {
n *= p[i];
}
for (int i = 0 ; i < len ; i++) {
i64 m = n / p[i];
i64 x, y;
Exgcd(m, p[i], x, y);
ans = (ans + (__int128) a[i] * m % n * x % n + n) % n;
}
return ans;
}
|
例题
P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪 - 洛谷
拓展中国剩余定理
模版
| C++ |
|---|
| i64 Exgcd(i64 a, i64 b, i64 &x, i64 &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
i64 d = Exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
i64 ExCRT(const vector<i64> &a, const vector<i64> &p) {
// ans % p_i = a_i
i64 n = p[0];
__int128 ans = a[0];
int len = a.size();
for (int i = 1 ; i < len ; i++) {
i64 x, y;
i64 c = (a[i] - ans % p[i] + p[i]) % p[i];
i64 d = Exgcd(n, p[i], x, y);
if (c % d != 0) {
return -1LL;
}
i64 g = p[i] / d;
x = (__int128) x * c / d % g;
ans += x * n;
n *= g;
ans = (ans % n + n) % n;
}
return ans;
}
|
例题
P4777 【模板】扩展中国剩余定理(EXCRT)- 洛谷