using ll = __int128;
template <typename T>
inline void rd(T &data) {
T x = 0, flag = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch=='-') flag = flag * -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
data = x * flag;
}
template <typename T>
void wt(T x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) wt(x / 10);
putchar(x % 10 + '0');
}
int n;
struct CRT {
constexpr static int N = 30;
ll a[N] {}, b[N] {};
CRT() = default;
CRT(int n) {
for (int i = 1; i <= n; ++i) {
rd(a[i]), rd(b[i]);
}
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) {
x = 1, y = 0;
return a;
}
ll d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
ll getCRT() { // 中国剩余定理
ll M = 1;
for (int i = 1; i <= n; i++) {
M *= a[i];
}
ll res = 0;
for (int i = 1; i <= n; i++) {
ll Mi = M / a[i];
ll x, y;
exgcd(Mi, a[i], x, y);
x = (x + a[i]) % a[i];
res += b[i] * Mi * x;
}
return res % M;
}
ll getEXCRT() { // 扩展中国剩余定理
bool flag = true;
ll a1 = a[1], b1 = b[1];
for (int i = 2; i <= n; i++) {
ll a2 = a[i], b2 = b[i], k1, k2;
ll d = exgcd(a1, a2, k1, k2);
if ((b2 - b1) % d) {
flag = false;
break;
}
k1 *= (b2 - b1) / d;
k1 = (k1 % (a2 / d) + a2 / d) % (a2 / d);
b1 = a1 * k1 + b1;
a1 = a1 / d * a2;
if (a1 < 0) {
a1 = -a1;
}
}
if (!flag) {
return -1;
} else {
return (b1 % a1 + a1) % a1;
}
}
};
标签:剩余,ch,CRT,int,定理,flag,ll,模板,getchar
From: https://www.cnblogs.com/hacker-dvd/p/17122167.html