线性代数(长期更新)
矩阵
概念
定义:设
记
看起来比较牛。
矩阵乘法
设
其中
卡常技巧:或许在数字不大的时候可以用long long/__int128
存下
性质
结合律
分配律
单位元
对
称为
不满足消去律和交换律
与常系数齐次线性递推
由于矩阵乘法的结合律,可以用快速幂计算
对于常系数齐次线性递推,可以构造转移矩阵
邻接矩阵的矩阵乘法
对于一个有向图
对比一下矩阵乘法和Floyd,发现很像。可以知道
如果只关心可达性,则将bitset
,
这种板子题中变形一下就要拆点,尽量将拆边换成拆点,因为边数可以轻易达到
矩阵乘法优化DP
那是DP的问题。
通常范围会很大,但是先别管,推出朴素的DP式子再说。
一般来讲这里的DP式子不会很长(没有
如果DP式子很长,那么考虑差分一下去掉求和号,让DP式子变短(就是把相同的部分去掉)。
如果有类似标记/隔断之类的特殊情况,就在这个地方停下来特殊转移。
动态DP
因为矩阵乘法的结合律,可以把DP写成一串转移矩阵乘起来的样子,然后可以用数据结构支持修改/在一个区间(范围)中做DP。几乎是数据结构题。常见会用
高斯消元/高斯约旦消元
要解
线性方程组的初等变换和高斯消元法
-
交换两个方程的位置。
-
用一个非零数乘某一方程的两边。
-
将一个方程的
倍加到另一个方程上。
可以发现初等变换不改变线性方程组的解。
那么我们可以通过初等变换很容易将原来的线性方程组变成上阶梯形的样子,且每个系数不全为
设化为上阶梯形后,有
-
若
且 不全为 ,则方程组无解。 -
若
,或者 时 全为 ,方程组有解。
在有解的情况下,继续讨论唯一解还是无穷多解:
-
当
时,有唯一解,可以从上阶梯形的右下角开始向上递推出每个变量的值。 -
当
时,有无穷多解, 可以在数域中任取,剩下的变量值由其决定。
高斯约旦消元法
首先将方程组看成增广矩阵。
高斯约旦消元将矩阵消成对角线。
怎么实现呢?
通过初等变换:交换两行,两行做加减。可以发现这在解方程上是没有影响的。
步骤:
-
按列遍历,将操作行交换至当前行。
-
从当前操作行以及未操作行中找到系数最大的一项,在其他行中将这一主元的系数消成
。 -
重复前两步。
重要性质:
-
每次消元后当前列只有当前行上不为
。 -
当前行上,当前列左边的数均为
。
这样就可以直接做有唯一解的情况了。
那么无解和无穷多解怎么判呢?
首先很显然的,如果有一行中系数全为
在高斯约旦消元中,出现无解/无穷多解,则存在某一行找不到主元(即当前行与下面的行中,系数都为
我们发现,第一次找不到主元时,仍满足上面的性质,那么我们只需维护这一性质,即只用维持当前行不变,处理下一列即可。
处理完后,对于未操作的行,其中的系数都为
那么判断无解/无穷多解只需判断系数全为
若没有常数项全为
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=60;
const double eps=1e-5;
int x;
struct mat{
double num[maxn][maxn];
void GuassJordan(int n,int m){
int r=1;
for(int i=1;i<=n;++i){
int tmp=r;
for(int j=r+1;j<=n;++j){
if(fabs(num[j][i])>fabs(num[tmp][i])){
tmp=j;
}
}
if(fabs(num[tmp][i])<eps) continue;
swap(num[r],num[tmp]);
for(int k=1;k<=n;++k){
if(r==k) continue;
for(int j=i+1;j<=m;++j) num[k][j]-=num[k][i]/num[r][i]*num[r][j];
}
r++;
}
r--;
if(r<n){
for(int i=r+1;i<=n;++i){
if(fabs(num[i][m])>eps){
puts("-1");
return;
}
}
puts("0");
return;
}
for(int i=1;i<=n;++i){
num[i][m]/=num[i][i];
if(fabs(num[i][m])<eps) num[i][m]=0;
printf("x%d=%.2lf\n",i,num[i][m]);
}
return;
}
}matrix;
int main(){
scanf("%d",&x);
for(int i=1;i<=x;++i){
for(int j=1;j<=x+1;++j){
scanf("%lf",&matrix.num[i][j]);
}
}
matrix.GuassJordan(x,x+1);
return 0;
}
时间复杂度
从当前行往下找操作行时,一般选当前主元系数最大的一行,可以减小误差。否则在卡精度的题中精度不够。
解空间
一堆概念来了
向量
定义:数域
-
加法:对于
, 。 -
数乘:对于
, 。
线性相关性
-
线性组合:设
, ,称 是 的一个线性组合。 -
线性表示:设
,如果 可以写成 的一个线性组合,那么称 可由 线性表示(或者线性表出)。 -
线性相关:设
,若存在一组不全为 的数 ,使得 ,则称 线性相关,否则称之线性无关,即任取一组不全为 的数 , 。
对于第三点,等价地,
极大无关组
对于
-
线性无关。
-
每个
都可以由之线性表出。
那么称之为
显然有:设
设
向量空间
设
记
进一步,当两组向量张成的子空间相同时,称两组向量是等价的。
定理:若
设
线性方程组与矩阵
线性方程组可以写成矩阵形式:
由此可得两个矩阵:
-
系数矩阵
。 -
增广矩阵
矩阵的初等变换:与线性方程组的初等变换一一对应的。有初等行变换和初等列变换。
行空间,列空间
-
由
的 个行向量张成的 的子空间称为 的行空间,其维数称为矩阵 的行秩,记作 。 -
由
的 个列向量张成的 的子空间称为 的列空间,其维数称为矩阵 的列秩,记作 。
定理:矩阵的初等行、列变换不改变矩阵的行秩和列秩。
矩阵的秩
定理:
于是定义
定理:
线性方程组的解
定理:
进一步,若
-
时,有唯一解。 -
时,有无穷多解。
齐次线性方程组解的结构
设原线性方程组的系数矩阵
设
令
直接验证,
定理:设
一般线性方程组解的结构
设原线性方程组的系数矩阵
其相伴的齐次线性方程组(或导出组):
设
定理:设
换言之,设
线性基
OI中一般都用异或线性基。是在数域
功能:
-
判断
是否能被数集中的数异或出来。 -
求一个数表示成数集中某些数异或和的方案数。
-
求数集的所有子集的异或和中最大/最小/第
大/第 小。 -
求一个数在数集的所有子集的异或和中的排名。
或许还可以发扬人类智慧来实现其他功能。
构造
我们贪心地构造一个数集
若
我们将线性基排序,保证其形如上三角矩阵,即第
如何构造呢?我们考虑把数逐个插入线性基中(即维护了当前的向量所张成的空间的基底)。
设当前要插入
容易发现这很对。正确性确实显然。
除了贪心的构造方式,还可以高斯消元,但我不会。
性质
-
原序列任意一个数都可以通过线性基中的一些数异或得到:因为线性基是原序列所张成的空间的一组基底。
-
线性基内任意数不能做异或得到
:显然的,因为线性基中的向量是线性无关的,所以无法用一些线性基中的向量表示另一个线性基中的向量,即不可能异或得到 。 -
线性基中的元素个数是在满足性质一的前提下最少的:显然的。
基本操作
插入
同构造,直接代码实现。
void ins(ll x){
for(int i=50;i>=0;--i){
if((x>>i)&1){
if(w[i]) x^=w[i];
else{
w[i]=x;
break;
}
}
}
}
判断 能否被异或出来(存在性)
尝试插入
求数集的所有子集中最大异或和
贪心地,从线性基最高位开始尝试异或上线性基中的这个元素,取
ll getmx(){
ll mx=0;
for(int i=50;i>=0;--i){
if(!w[i]) continue;
mx=max(mx,mx^w[i]);
}
return mx;
}
更改初值为
最小异或和
要检查是否有元素不能插入线性基,如果有,那么答案为
线性基求并
把小的逐个插入大的即可,不能插入的就忽略。
有可重复贡献性,可以进行类似ST表的操作。
带删除线性基
这里的线性基没有消元。
离线算法
记录下每个元素的删除时间,插入时优先将删除时间更晚的放在基里面。如果删了基外面的元素,不管。删了基里面的元素,那就在操作时略去这个元素。
在线算法
咕咕咕。
行列式
定义
行列式只对方阵有定义。
设
先定义一下余子式和代数余子式。
对于
递归地定义行列式:
-
若
, 。 -
若
, (都是第一列上的元素)。
这个的等价定义是:
令
矩阵的初等变换对于行列式的影响
-
交换
中不同的两行得到 ,那么 。 -
将
中的一行整体乘上 得到 ,那么 。 -
将
中某一行的 倍加到另外一行上得到 ,那么 。
还有一个定理:
求法
利用初等变换对行列式的影响,我们对行列式进行高斯消元使之变成上三角矩阵,然后行列式的值就是主对角线上所有元素的乘积。
一定要注意交换两行时
一个定理:
一个定理:
范德蒙德行列式
这个行列式很特殊,可以
形如:
推一下,我们先把第一列给消了,把第一行乘上
然后按第一列展开:
把
所以就可以得到
介绍一些概念和定理
可逆矩阵
设
可以证明,若
性质
-
若
可逆,则 。 -
若
都是 阶可逆矩阵,那么 也可逆,且 。一般地,若 都是 阶可逆矩阵,那么 。 -
若
可逆,则 可逆,且 。 -
伴随矩阵
其中的
一个定理:
相当于将第
性质
-
。由上面的定理硬算 即可得到。 -
,由上面那条性质可以得到。
初等变换的矩阵表示
初等行变换可以表示为左乘一个矩阵,初等列变换可以视为右称一个矩阵。
称这些矩阵为初等矩阵
初等矩阵之一
交换
初等矩阵之二
用
初等矩阵之三
初等矩阵的性质
都是可逆矩阵。
怎么进行初等变换
设
:交换 的第 行和第 行所得矩阵。 :将 的第 行乘上 所得矩阵。 :将 的第 行的 倍加到第 行所得矩阵。
设
:交换 的第 列和第 列所得矩阵。 :将 的第 列乘上 所得矩阵。 :将 的第 行的 倍加到第 行所得矩阵。(这里对比上面, 交换了位置)
应用
-
Matrix-Tree定理
-
LGV引理
这两个去看计数。
Cramer's rule
若一个线性方程组的系数矩阵
其中
证明:给左边乘上个
特征值与特征多项式
特征值与特征向量
在
若非零向量
则称
此时有:
这个方程有非零解的充要条件是
特征多项式
设
是一个关于
求法
拉插
把
但是有
利用上Hessenberg矩阵
对于
相似变换不会改变矩阵的行列式和特征多项式,这是容易证明的。(考虑
把
Schur's Lemma:
设
上三角矩阵的特征多项式是好求的,Schur's Lemma也证明了存在
退而求其次,我们考虑消成上Henssenberg矩阵。
对于
的矩阵我们称之为上Hessenberg矩阵,
记
先来观察一下下
-
, (我们定义它为 )。 -
, 。 -
,
考虑不断对最后一行展开,要么直接选
性质
先介绍概念
首先
我们可以选取
对于
于是存在不全为零的
记
我们称满足
设
性质:
Cayley-Hamilton定理
设
即
考虑证明,有一个引理:
有了这个引理后,由Schur's Lemma,总是有相似变换
设
设
于是
应用:
对于一个关于矩阵
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)