行列式学习笔记(二)
上次介绍了行列式的基本性质,我们继续探索由性质得出的有用结论(以二阶行列式为基准)。
结论一
如果行列式两行相同,则行列式的值是 \(0\) 。
证明:
\[\because
\begin{vmatrix}
a&b\\
c&d\\
\end{vmatrix}
=-\begin{vmatrix}
c&d\\
a&b\\
\end{vmatrix}\\
\therefore
\begin{vmatrix}
a&b\\
a&b\\
\end{vmatrix}
=-\begin{vmatrix}
a&b\\
a&b\\
\end{vmatrix}=0
\]
结论二
如果有一行是 \(0\) 则行列式值是 \(0\)
证明:
我们假设第一行是 \(0\) 。
\[\because
\begin{vmatrix}
ka&kb\\
c&d\\
\end{vmatrix}
=k\begin{vmatrix}
a&b\\
c&d\\
\end{vmatrix}\\
\begin{split}
\therefore
\begin{vmatrix}
0&0\\
c&d\\
\end{vmatrix}
&=
\begin{vmatrix}
0\times a& 0 \times b\\
c&d\\
\end{vmatrix}\\
&=
0\times\begin{vmatrix}
a&b\\
c&d\\
\end{vmatrix}\\
&=0
\end{split}
\]
结论三
如果一行是另一行的 \(k\) 倍,则答案为 \(0\) 。
证明:
我们假设第一行是第二行的 \(k\) 倍。
\[\begin{split}
\det(A) &=
\begin {vmatrix}
ka &kb\\
a &b\\
\end {vmatrix}\\
&=k
\begin{vmatrix}
a & b\\
a & b\\
\end {vmatrix}
\end{split}
\]
由结论一可知:
\[\begin{vmatrix}
a & b\\
a & b\\
\end{vmatrix}
= 0\\
\therefore
\det(A) = k
\begin{vmatrix}
a & b\\
a & b\\
\end {vmatrix}=0
\]
结论四
如果某一行是其他行的线性组合,行列式的值是 \(0\) 。
证明:
\[\begin{split}
\det (A) &=
\begin {vmatrix}
a & b &c\\
d&e&f\\
k_1a+k_2d&k_1b+k_2e&k1_c+k_2f\\
\end {vmatrix}\\
&=
\begin {vmatrix}
a&b&c\\
d&e&f\\
k_1a&k_1b&k_1c\\
\end {vmatrix}+
\begin {vmatrix}
a&b&c\\
d&e&f\\
k_2d&k_2e&k_2f\\
\end {vmatrix}\\
&= 0 + 0 = 0
\end{split}\\
\]
计算行列式
先来介绍一个很好的性质。
一个行列式的一行加(减)另一行的 \(k\) 倍,行列式的值不变。
用数学公式表达:
\[\begin {vmatrix}
a&b&c\\
d&e&f\\
g&h&i\\
\end {vmatrix}
=
\begin {vmatrix}
a&b&c\\
d&e&f\\
g-ka&h-kb&i-kc\\
\end {vmatrix}
\]
证明一下:
\[\begin {split}
\det (A) &=
\begin {vmatrix}
a&b&c\\
d&e&f\\
g-ka&h-kb&i-kc\\
\end {vmatrix}\\
&=
\begin {vmatrix}
a&b&c\\
d&e&f\\
g&h&i\\
\end {vmatrix}
-
\begin {vmatrix}
a&b&c\\
d&e&f\\
ka&kb&kc\\
\end {vmatrix}\\
&=
\begin {vmatrix}
a&b&c\\
d&e&f\\
g&h&i\\
\end {vmatrix} \\
\end {split}
\]
直接对行列式进行 \(Gauss-Jordan\) 消元。
之后矩阵变成这样的一个存在,也就是对角矩阵。
\[\det(A)
=
\begin {vmatrix}
a_1 & 0 & \cdots &0\\
0 & a_2 & \cdots &0\\
\vdots & \vdots & \ddots &\vdots\\
0&0&\cdots & a_n\\
\end {vmatrix}
\]
考虑对角矩阵的行列式求法。
\[\begin {split}
\det(A) &=
\begin {vmatrix}
a_1 & 0 & \cdots &0\\
0 & a_2 & \cdots &0\\
\vdots & \vdots & \ddots &\vdots\\
0&0&\cdots & a_n\\
\end {vmatrix} \\
&= a_1 \times
\begin {vmatrix}
1 & 0 & \cdots &0\\
0 & a_2 & \cdots &0\\
\vdots & \vdots & \ddots &\vdots\\
0&0&\cdots & a_n\\
\end {vmatrix} \\
&=a_1 a_2\times
\begin {vmatrix}
1 & 0 & \cdots &0\\
0 & 1 & \cdots &0\\
\vdots & \vdots & \ddots &\vdots\\
0&0&\cdots & a_n\\
\end {vmatrix} \\
&= a_1 a_2 a_3 \cdots a_{n-1}a_n\times
\begin {vmatrix}
1 & 0 & \cdots &0\\
0 & 1 & \cdots &0\\
\vdots & \vdots & \ddots &\vdots\\
0&0&\cdots & 1\\
\end {vmatrix} \\
&= a_1a_2a_3\cdots a_{n-1}a_n\\
&= \prod_{i=1}^n a_i
\end {split}
\]
进一步的,我们推广到上三角矩阵以及下三角矩阵
发现这样的情况:
我们定义对角线的值为 \(a_1,a_2,\cdots,a_{n-1},a_n\) 。
那么,行列式的值都是
\[\prod_{i=1}^n a_i
\]
所以不需要 \(Gauss-Jordan\) 直接 \(Gauss\) 就可以啦!
Code
#include <bits/stdc++.h>
#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define quad putchar(' ')
#define Enter putchar('\n')
#define int long long
#define N 605
int n, mod, a[N][N], flag = 1;
signed main(void) {
// file("P7112");
std::cin >> n >> mod;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%lld", &a[i][j]);
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
while (a[i][i]) {
int x = a[j][i] / a[i][i];
for (int k = i; k <= n; k++)
a[j][k] = (a[j][k] - x * a[i][k] % mod + mod) % mod;
std::swap(a[j], a[i]);
flag *= (-1);
}a
std::swap(a[i], a[j]);
flag *= -1;
}
}
int ans = 1;
for (int i = 1; i <= n; i++)
ans = (ans * a[i][i]) % mod;
std::cout << (ans * flag + mod) % mod<< std::endl;
}