题目大意:给你一些关于$x$的方程组:
$$
egin{cases}
xequiv a_1pmod{mod_1}\
xequiv a_2pmod{mod_2}\
vdots\
xequiv a_npmod{mod_n}
end{cases}
$$
求解$x$的最小非负整数解($gcd(mod_1,mod_2,cdots,mod_n)
ot=1$)
题解:$EXCRT$,假设有两个方程
$$
egin{cases}
xequiv x_1pmod{A}\
xequiv x_2pmod{B}
end{cases}\
设g=gcd(A,B),k=leftlfloordfrac xg
ight
floor,c=xmod g\
x=kg+c\
所以x_1equiv x_2equiv cpmod g\
egin{cases}
kg+cequiv x_1pmod A\
kg+cequiv x_2pmod B\
end{cases}\
令k_1=leftlfloordfrac {x_1}g
ight
floor,k_2=leftlfloordfrac {x_2}g
ight
floor\
egin{cases}
kg+cequiv k_1g+cpmod A\
kg+cequiv k_2g+cpmod B\
end{cases}\
egin{cases}
kgequiv k_1gpmod A\
kgequiv k_2gpmod B\
end{cases}\
egin{cases}
kequiv k_1pmod{leftlfloordfrac Ag
ight
floor}\
kequiv k_2pmod{leftlfloordfrac Bg
ight
floor}\
end{cases}\
这样就可以用CRT解决了
$$
$CRT$部分见博客
卡点:无
C++ Code:
#include <cstdio>
long long gcd(const long long a, const long long b) {
if (!b) return a;
return gcd(b, a % b);
}
inline long long lcm(const long long a, const long long b) { return a / gcd(a, b) * b; }
inline long long mul(const long long x, const long long y, const long long mod) {
static long long res;
res = x * y - static_cast<long long> (static_cast<long double> (x) * y / mod + 0.5) * mod;
return res + (res >> 63 & mod);
}
void exgcd(const long long a, const long long b, long long &x, long long &y) {
if (!b) x = 1, y = 0;
else exgcd(b, a % b, y, x), y -= a / b * x;
}
inline long long inv(const long long a, const long long mod) {
static long long x, y;
exgcd(a, mod, x, y);
return x + (x >> 63 & mod);
}
inline long long getreduce(const long long x, const long long mod) { return x + (x >> 63 & mod); }
long long CRT(const long long A, const long long mod1, const long long B, const long long mod2) {
const long long mod = mod1 * mod2, inv1 = inv(mod1, mod2);
return getreduce(mul(mul(getreduce((B - A) % mod2, mod2), inv1, mod2), mod1, mod) + A, mod);
}
long long EXCRT(const long long A, const long long mod1, const long long B, const long long mod2) {
if (A % mod2 == B) return A;
const long long GCD = gcd(mod1, mod2), t = CRT(A / GCD, mod1 / GCD, B / GCD, mod2 / GCD);
return t * GCD + (A % GCD);
}
int n;
int main() {
scanf("%d", &n);
long long LCM = 1, ans = 0;
for (int i = 0; i < n; ++i) {
static long long a, b;
scanf("%lld%lld", &a, &b); b %= a;
ans = EXCRT(ans, LCM, b, a);
LCM = lcm(LCM, a);
}
printf("%lld
", ans);
}