P4777 【模板】扩展中国剩余定理(EXCRT)
题目链接:https://www.luogu.com.cn/problem/P4777
解题思路:完全来自 oi.wiki
注意:中间过程有一步可能会超 long long,得开 int128(代码第 \(39\) 行,因为这里有三个数相乘了)
示例程序:
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1;
y = 0;
return a;
}
ll d = exgcd(b, a%b, x, y);
ll t = x;
x = y;
y = t - a / b * y;
return d;
}
ll gcd(ll a, ll b) {
return b ? gcd(b, a%b) : a;
}
ll lcm(ll a, ll b) {
return a / gcd(a, b) * b;
}
ll excrt(vector<pair<ll, ll>> crts) {
ll m1 = 1, r1 = 0;
for (auto &[m2, r2] : crts) {
if (m1 == m2) {
if (r1 != r2) return -1;
continue;
}
ll p, q;
ll d = exgcd(m1, -m2, p, q);
if ((r2 - r1) % d) {
return -1;
}
ll M = lcm(m1, m2);
__int128 R = (__int128) m1 * p * ((r2-r1)/d) + r1;
m1 = M;
r1 = (R % M + M) % M;
}
return r1;
}
int main() {
int n;
scanf("%d", &n);
vector<pair<ll, ll>> crts(n);
for (int i = 0; i < n; i++)
scanf("%lld%lld", &crts[i].first, &crts[i].second);
ll ans = excrt(crts);
printf("%lld\n", ans);
return 0;
}
浙公网安备 33010602011771号