Loading

[笔记] 矩阵

行列式

\(\det(A)=\sum_{\sigma\in S_n}\operatorname{sgn}(\sigma)\prod_{i=1}^na_{i,\sigma(i)}\)

其中 \(S_n\) 是指长度为 \(n\) 的全排列的集合,\(\sigma\) 就是一个全排列,如果 \(\sigma\) 的逆序对对数为偶数,则 \(\operatorname{sgn}(\sigma)\),否则 \(\operatorname{sgn}(\sigma)=-1\)

  • 矩阵转置,行列式不变;
  • 矩阵行(列)交换,行列式取反;
  • 矩阵行(列)相加或相减,行列式不变;
  • 矩阵行(列)所有元素同时乘以数 \(k\),行列式也乘 \(k\)

行列式求值

  • 如果不需要取模或者模数为质数,则直接高斯消元,否则辗转相除。
int det(){
	int tg = 1, res = 1;
	lfor(i, 1, n){
		int k = i;
		lfor(j, k + 1, n) if(a[j][i] > a[k][i]) k = j;
		if(!a[k][i]) return 0;
		if(i != k) swap(a[k], a[i]), tg = -tg;
		lfor(j, i + 1, n){
			while(a[j][i]){
				int x = a[i][i] / a[j][i];
				lfor(k, i, n) a[i][k] = (a[i][k] + 1LL * (p - x) * a[j][k]) % p;
				swap(a[j], a[i]), tg = -tg;
			}
		}
		res = 1LL * res * a[i][i] % p;
	}
	res *= tg; return (res + p) % p;
}

矩阵求逆

在高斯消元的同时对单位矩阵做同样的操作。

bool Inv(){
	lfor(i, 1, n){
		int k = i; 
		lfor(j, i + 1, n) if(a.a[j][i]){ k = j; break; }
		if(!a.a[k][i]) return 0;
		if(k != i) a.Swap(k, i), inv.Swap(k, i);
		inv.mul(i, qpow(a[i][i])), a.mul(i, qpow(a[i][i]));
		lfor(j, 1, n) if(i != j) 
			inv.add(j, i, mod - a[j][i]), a.add(j, i, mod - a[j][i]);
	}
	return 1;
}

积和式

\(\operatorname{perm}(A)=\sum_{\sigma\in S_n}\prod_{i=1}^na_{i,\sigma(i)}\)

  • \(\bmod 2\) 意义下等于行列式。

矩阵的秩

\(\operatorname{rank}(A)=A\) 中能选出的最多的线性无关的行数。

如果某一行能被其它的行组合出来,则称他们线性相关。

LGV 引理

关键词:路径交点

  • 矩阵 \(a_{i,j}\) 权值为第 \(i\) 个起点到第 \(j\) 个终点的路径条数,则 \(\det(A)\) 即为第 \(i\) 个起点到第 \(i\) 个终点,\(n\) 条路径无交点的方案数。
  • 可能存在条件限制和变式。

矩阵乘法的常数优化

  • 对于较小的矩阵,在运算需要取模是,可以使用 long long,在 \(O(n^3)\) 次乘法后进行 \(O(n^2)\) 的取模。

矩阵乘法的应用

  • 加速递推;
  • 加速 DP 转移;
  • 有一些修改操作,用矩阵乘法可以很好地表达。

题目

「THUSCH 2017」大魔法师

posted @ 2022-02-16 15:14  IrisT  阅读(213)  评论(0编辑  收藏  举报