同余问题共7part,我的博客链接:
多元线性同余方程
形如: a 1 x 1 + a 2 x 2 + ⋯ + a n x n ≡ b ( m o d m ) a_1x_1+a_2x_2+\cdots+a_nx_n\equiv b(\mod m) a1x1+a2x2+⋯+anxn≡b(modm)
由 a 1 x + a 2 y = gcd ( a 1 , a 2 ) a_1x+a_2y=\gcd(a_1,a_2) a1x+a2y=gcd(a1,a2) 有解可知左式能表达 c gcd ( a 1 , a 2 ) , c ∈ N c\gcd(a_1,a_2),c\in N cgcd(a1,a2),c∈N ;引入 a 3 a_3 a3 ,则 g c d ( a 1 , a 2 ) x + a 3 y gcd(a_1,a_2)x+a_3y gcd(a1,a2)x+a3y 可以表示 c gcd ( a 1 , a 2 , a 3 ) , c ∈ N c\gcd(a_1,a_2,a_3),c\in N cgcd(a1,a2,a3),c∈N 。以此类推, a 1 x 1 + a 2 x 2 + ⋯ + a n x n a_1x_1+a_2x_2+\cdots+a_nx_n a1x1+a2x2+⋯+anxn 可以表达 c gcd ( a 1 , a 2 , ⋯ , a n ) , c ∈ N c\gcd(a_1,a_2,\cdots,a_n),c\in N cgcd(a1,a2,⋯,an),c∈N ,因此有解的条件为 gcd ( a 1 , a 2 , ⋯ , a n , m ) ∣ b \gcd(a_1,a_2,\cdots, a_n,m)\mid b gcd(a1,a2,⋯,an,m)∣b 。
一个很好理解的推导:我们将 m m m 添加到 a a a 数列中,仍设数量为 n n n 。设 d = gcd ( a 1 , a 2 , ⋯ , a n ) , d 1 = gcd ( a 1 , a 2 , ⋯ , a n − 1 ) d=\gcd(a_1,a_2,\cdots, a_n),d_1=\gcd(a_1,a_2,\cdots, a_{n-1}) d=gcd(a1,a2,⋯,an),d1=gcd(a1,a2,⋯,an−1) ,于是有 gcd ( d 1 , a n ) = d \gcd(d_1,a_n)=d gcd(d1,an)=d ,则原式转化为 a n x n + d 1 k = b a_nx_n+d_1k=b anxn+d1k=b ,可以通过前面一元线性同余方程的解法解出 x n , k x_n,k xn,k ,则问题转化为 a 1 x 1 + a 2 x 2 + ⋯ + a n − 1 x n − 1 = d 1 ∗ k a_1x_1+a_2x_2+\cdots+a_{n-1}x_{n-1}=d_1*k a1x1+a2x2+⋯+an−1xn−1=d1∗k,仍采取相同的解法。
但
O
(
n
2
)
O(n^2)
O(n2) 求每次的
gcd
\gcd
gcd 显然不现实。设
d
i
=
gcd
(
a
1
,
a
2
,
⋯
,
a
i
)
d_i=\gcd(a_1,a_2,\cdots,a_{i})
di=gcd(a1,a2,⋯,ai) ,
x
[
1...
n
]
x[1...n]
x[1...n] 表示解(从
1
1
1 标号,
a
[
n
+
1
]
a[n+1]
a[n+1] 是
m
m
m )则可以求解
d
i
X
i
+
a
i
+
1
y
i
=
d
i
+
1
d_iX_i+a_{i+1}y_i=d_{i+1}
diXi+ai+1yi=di+1 的
X
i
,
y
i
X_i,y_i
Xi,yi 。
观察最后一个式子:
d
n
X
n
+
a
n
+
1
y
n
=
d
n
+
1
d_{n}X_{n}+a_{n+1}y_{n}=d_{n+1}
dnXn+an+1yn=dn+1 要求解答案,等式两边乘上
c
=
b
d
n
+
1
c=\frac{b}{d_{n+1}}
c=dn+1b ,所以
x
n
+
1
=
y
n
c
b
−
a
n
+
1
x
n
+
1
=
d
n
X
n
c
x_{n+1}=y_{n}c\\b-a_{n+1}x_{n+1}=d_{n}X_{n}c
xn+1=yncb−an+1xn+1=dnXnc 则前一个式子
d
n
−
1
X
n
−
1
+
a
n
y
n
−
1
=
d
n
d_{n-1}X_{n-1}+a_{n}y_{n-1}=d_{n}
dn−1Xn−1+anyn−1=dn 要求解答案,等式两边乘上
c
′
=
c
X
n
c'=cX_{n}
c′=cXn ,依次求解即可。
// 求解a1x1+a2x2+...+anxn==b mod m,a从1开始标号
int X[N], y[N];
bool mod_Xn_equation(int a[], int b, int m, int n, int x[])
{
a[n + 1] = m;
int d = a[1];
for (int i = 2; i <= n + 1; i++)
exgcd(d, a[i], X[i - 1], y[i - 1]);
if (b % d)
return false;
int c = b / d;
x[n + 1] = y[n] * c;
y[0] = 1;
for (int i = n; i >= 1; i--)
{
c = (c * X[i] % m + m) % m;
x[i] = (y[i - 1] * c % m + m) % m;
}
return true;
}