行列式与矩阵相关与应用

行列式

行列式的概念

记一个 n × n n \times n n×n行列式为:

D = ∥ a 11 a 12 . . . a 1 n a 21 a 22 . . . a 2 n . . . . . . . . . . . . a n 1 a n 2 . . . a n n ∥ D=\left\| \begin{matrix} a_{11} & a_{12} & ... & a_{1n} \\ a_{21} & a_{22} & ... & a_{2n} \\ ... & ... & ... & ... \\ a_{n1} & a_{n2} & ... & a_{nn} \end{matrix} \right\| D=a11a21...an1a12a22...an2............a1na2n...ann

计算结果为:

∑ ( − 1 ) t a 1 p 1 a 2 p 2 a 3 p 3 . . . a n p n \sum (-1)^t a_{1p_1}a_{2p2}a_{3p_3}...a_{np_n} (1)ta1p1a2p2a3p3...anpn

其中t是排列 p 1 , p 2 . . . p n p_1,p_2...p_n p1,p2...pn的逆序对个数。

也可以记忆一下,二阶行列式是 a 11 a 22 − a 12 a 21 a_{11}a_{22}-a_{12}a_{21} a11a22a12a21

行列式的求法

性质1:交换行列式的两行,行列式的值会变成它的相反数。

证明:比如交换第i行和第j行,那么行列式由 ∑ ( − 1 ) t 1 . . . a i p i . . . a j p j . . . \sum (-1)^{t_1}...a_{ip_i}...a_{jp_j}... (1)t1...aipi...ajpj...变成了 ∑ ( − 1 ) t 2 . . . a j p j . . . a i p i . . . \sum (-1)^{t_2}...a_{jp_j}...a_{ip_i}... (1)t2...ajpj...aipi...,相当于把每一个排列都交换了两个元素,这样这个排列的逆序对数奇偶性一定会改变:

若只看每个数前面比其大的数,如果 p i &gt; p j p_i&gt;p_j pi>pj,那么在 p j p_j pj前面比其大的数的个数减1,而原来在 p j p_j pj前面,现在不在的比 p j p_j pj大的数,如果比 p i p_i pi大,则无影响。否则它们前面失去了一个比它们大的 p i p_i pi,个数都减1,而 p j p_j pj失去了它们,个数也减一,相当于奇偶性不变. p i &lt; p j p_i&lt;p_j pi<pj可以视作考虑每个数后面的比其小的数的个数,也同理。

那么每个 t 1 t_1 t1一定和 t 2 t_2 t2奇偶性不同。
性质2:某一行乘以一个相同的数,加在另一行上,行列式不变。

证明:相当于变成 ∑ x ( − 1 ) t a 1 p 1 a 2 p 2 a 3 p 3 . . . a n p n \sum x(-1)^t a_{1p_1}a_{2p2}a_{3p_3}...a_{np_n} x(1)ta1p1a2p2a3p3...anpn,由于行列式系数为正的项数和为负的相等,所以答案不变。

性质3:

D = ∥ a 11 0 0 . . . 0 a 21 a 22 0 . . . 0 . . . . . . . . . . . . . . . a n 1 a n 2 a n 3 . . . a n n ∥ = ∏ a i i D=\left\| \begin{matrix} a_{11} &amp; 0 &amp;0 &amp;... &amp; 0 \\ a_{21} &amp; a_{22} &amp;0 &amp;... &amp; 0 \\ ... &amp; ... &amp; ... &amp; ...&amp;... \\ a_{n1} &amp; a_{n2} &amp; a_{n3} &amp;... &amp; a_{nn} \end{matrix} \right\|=\prod a_{ii} D=a11a21...an10a22...an200...an3............00...ann=aii
性质4:某一行同时乘以一个相同的数,行列式也要乘以那个数。

由上述性质,我们可以得到一种类似于高斯消元的求矩阵行列式的方法(例题:spoj-DETER3):

#include<bits/stdc++.h>
using namespace std;
#define LL long long
int n;LL p,a[205][205];
LL work() {
	LL re=1;
	for(int j=1;j<=n;++j) {
		int id=j; while(id<=n&&!a[id][j]) ++id;
		if(id>n) return 0;
		if(id!=j) swap(a[j],a[id]),re=-re;
		for(int i=j+1;i<=n;++i)
			while(a[i][j]) {
			LL t=a[j][j]/a[i][j];
			for(int k=j;k<=n;++k) a[j][k]=(a[j][k]-a[i][k]*t)%p;
			swap(a[j],a[i]),re=-re;
		}
		re=(re*a[j][j])%p;
	}
	return (re%p+p)%p;
}
int main() {
    while(~scanf("%d%lld",&n,&p)) {
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=n;++j) scanf("%lld",&a[i][j]),a[i][j]%=p;
    	printf("%lld\n",work());
    }
    return 0;
}

按行(列)展开

余子式:一个行列式去掉它的第i行和第j列得到的行列式称为它的余子式,记做 M i j M_{ij} Mij

代数余子式 a i j = ( − 1 ) i + j M i j a_{ij}=(-1)^{i+j}M_{ij} aij=(1)i+jMij

行列式等于它的任一行(列)各元素与其对应的代数余子式乘积之和,即

D = a i 1 A i 1 + a i 2 A i 2 + . . . + a i n A i n ( i = 1 , 2... n ) D=a_{i1}A_{i1}+a_{i2}A_{i2}+...+a_{in}A_{in} (i=1,2...n) D=ai1Ai1+ai2Ai2+...+ainAin(i=1,2...n)

D = a 1 j A 1 j + a 2 j A 2 j + . . . + a n j A n j ( j = 1 , 2... n ) D=a_{1j}A_{1j}+a_{2j}A_{2j}+...+a_{nj}A_{nj}(j=1,2...n) D=a1jA1j+a2jA2j+...+anjAnj(j=1,2...n)

这就是行列式按行(列)展开法则,可以简化行列式计算.

伴随矩阵:第i行j列为矩阵A的 a i j a_{ij} aij的矩阵被称为A的伴随矩阵,记做 A ∗ A^{*} A

应用

HDU5852

对于两个棋子的情况,如果路径不相交,则方案数为 C b 1 − a 1 + n − 1 n − 1 × C b 2 − a 2 + n − 1 n − 1 C_{b_1-a_1+n-1}^{n-1} \times C_{b_2-a_2+n-1}^{n-1} Cb1a1+n1n1×Cb2a2+n1n1,如果相交,则可以看其最下面的一个交点,交换该交点后的路径,可以把一个相交的关系看作两条从 a 1 a_1 a1 b 2 b_2 b2和从 a 2 a_2 a2 b 1 b_1 b1的路径,方案数为 C b 2 − a 1 + n − 1 n − 1 × C b 1 − a 2 + n − 1 n − 1 C_{b_2-a_1+n-1}^{n-1} \times C_{b_1-a_2+n-1}^{n-1} Cb2a1+n1n1×Cb1a2+n1n1

而多条路径相交的情况,则考虑容斥。那么相当于终点被打乱了,成为一个排列。而奇排列(逆序数为奇数的排列)一定是由一个从1到n的排列经过奇数次元素两两交换得到的(自己证),因此原问题可以转化为一个行列式问题。

此外,交这道题千万不要用C++,请用G++,不然会超时(别问我是怎么知道的)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const LL mod=1000000007;
int n,m,T;LL inv[200005],fac[200005];
int a[105],b[105];LL t[105][105];
LL ksm(LL x,LL y) {
	LL re=1;
	for(;y;x=x*x%mod,y>>=1) if(y&1) re=re*x%mod;
	return re;
}
void init() {
	fac[0]=inv[0]=1;
	for(LL i=1;i<=200000;++i) fac[i]=fac[i-1]*i%mod;
	inv[200000]=ksm(fac[200000],mod-2);
	for(int i=200000-1;i>=1;--i) inv[i]=inv[i+1]*(i+1)%mod;
}
LL C(LL d,LL u) {
	if(u>d) return 0;
	return fac[d]*inv[u]%mod*inv[d-u]%mod;
}
LL work() {
	LL re=1;
	for(int j=1;j<=m;++j) {
		int id=j; while(id<=m&&!t[id][j]) ++id;
		if(id>m) return 0;
		if(id!=j) swap(a[id],a[j]),re=-re;
		LL kl=ksm(t[j][j],mod-2);
		for(int i=j+1;i<=m;++i)
			if(t[i][j]) {
				re=re*kl%mod;//第i行乘t[j][j],相当于将行列式的值扩大了t[j][j]倍
				for(int k=m;k>=j;--k)
					t[i][k]=(t[i][k]*t[j][j]%mod-t[j][k]*t[i][j]%mod+mod)%mod;
			}
		re=(re*t[j][j])%mod;
	}
	return (re%mod+mod)%mod;
}
int main() {
    init(),scanf("%d",&T);
    while(T--) {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;++i) scanf("%d",&a[i]);
    	for(int i=1;i<=m;++i) scanf("%d",&b[i]);
    	for(int i=1;i<=m;++i)
    		for(int j=1;j<=m;++j) t[i][j]=C(n-1+b[i]-a[j],n-1);
    	printf("%lld\n",work());
    }
    return 0;
}

矩阵相关

矩阵的逆

使得矩阵 A A − 1 = I AA^{-1}=I AA1=I(I是单位矩阵)的 A − 1 A^{-1} A1 A A A的逆矩阵,且 A − 1 A = E A^{-1}A=E A1A=E
A − 1 = 1 ∣ A ∣ A ∗ A^{-1}=\frac{1}{|A|} A^{*} A1=A1A

矩阵的秩

在矩阵中任取 k k k k k k列,这些行列的交点处的元素取出来,不改变它们的相对位置,构成的一个行列式,称为该矩阵的 k k k阶余子式。如果一个矩阵A的任一 r r r阶子式不为 0 0 0,而所有 r + 1 r+1 r+1阶子式为 0 0 0,则 r r r称为 A A A的秩。

矩阵的秩等于阶数最大的非零余子式的阶数。

矩阵的特征值

若对于矩阵 A A A,存在一个向量 α \alpha α和一个实数 λ \lambda λ使得 A α = λ α A\alpha=\lambda \alpha Aα=λα则称 α \alpha α A A A的特征向量, λ \lambda λ A A A的特征值。

那么根据 ∣ λ I − A ∣ = 0 |\lambda I-A|=0 λIA=0可以解方程求出特征值,进而求出特征向量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值