中国剩余定理
设
m1,m2,...,mk
m
1
,
m
2
,
.
.
.
,
m
k
两两互质
则对于方程组
x≡a1(mod m1)
x
≡
a
1
(
m
o
d
m
1
)
x≡a2(mod m2)
x
≡
a
2
(
m
o
d
m
2
)
...
.
.
.
x≡ak(mod mk)
x
≡
a
k
(
m
o
d
m
k
)
有整数解
并且在模
M=Πmi
M
=
Π
m
i
的意义下解唯一
为
∑(ai∗M/mi)(mod M)
∑
(
a
i
∗
M
/
m
i
)
(
m
o
d
M
)
Exgcd E x g c d 一波求解就好了
证明:
对于方程组
x≡0(mod m1)
x
≡
0
(
m
o
d
m
1
)
x≡0(mod m2)
x
≡
0
(
m
o
d
m
2
)
...
.
.
.
x≡1(mod mi)
x
≡
1
(
m
o
d
m
i
)
...
.
.
.
x≡0(mod mk)
x
≡
0
(
m
o
d
m
k
)
就等价于求解
(M/mi)x≡1(mod mi)
(
M
/
m
i
)
x
≡
1
(
m
o
d
m
i
)
而如果
x≡c(mod mi)
x
≡
c
(
m
o
d
m
i
)
那么
a∗x≡a∗c(mod mi)
a
∗
x
≡
a
∗
c
(
m
o
d
m
i
)
扩展
求解模数不互质情况下的线性方程组
考虑合并两个方程组
x≡ai(mod mi)
x
≡
a
i
(
m
o
d
m
i
)
x≡ai+1(mod mi+1)
x
≡
a
i
+
1
(
m
o
d
m
i
+
1
)
写成
x=ai+x1∗mi=ai+1+x2∗mi+1
x
=
a
i
+
x
1
∗
m
i
=
a
i
+
1
+
x
2
∗
m
i
+
1
的形式
求
x
x
最小,那么可以先解出最小的解
x′
x
′
,带入就是
直接
Exgcd
E
x
g
c
d
求解
x1∗mi+x2∗mi+1=ai+1−ai
x
1
∗
m
i
+
x
2
∗
m
i
+
1
=
a
i
+
1
−
a
i
,就好了
合并之后
显然新的方程就是
x≡x′(mod lcm(mi,mi+1))
x
≡
x
′
(
m
o
d
l
c
m
(
m
i
,
m
i
+
1
)
)
就可以了
代码
# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
template <class Int>
IL void Input(RG Int &x){
RG int z = 1; RG char c = getchar(); x = 0;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= z;
}
IL ll ExGcd(RG ll a, RG ll b, RG ll &x, RG ll &y){
if(!b){
x = 1, y = 0;
return a;
}
RG ll d = ExGcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
const int maxn(1e5 + 5);
int n, flg;
ll ans, x, y, m[maxn], b[maxn];
int main(RG int argc, RG char* argv[]){
while(scanf("%d", &n) != EOF){
ans = flg = 0;
for(RG int i = 1; i <= n; ++i) Input(m[i]), Input(b[i]);
for(RG int i = 2; i <= n; ++i){
RG ll d = ExGcd(m[1], m[i], x, y), g = b[i] - b[1], t;
if(g % d){
flg = 1;
break;
}
x *= g / d, t = m[i] / d, x = (x % t + t) % t;
b[1] += m[1] * x, m[1] *= t, b[1] %= m[1];
}
if(flg) puts("-1");
else printf("%lld\n", (b[1] % m[1] + m[1]) % m[1]);
}
return 0;
}