复习笔记——线性代数
高斯消元
还是注意解的判断:
1.出现0=0:无数组解
2.出现0=1:无解
3.else:唯一解
实数版
typedef double db;
typedef db Mat[N][N];
bool gauss(Mat A,int n){
for(int i=1;i<=n;i++){
int r=i;
for(int j=i+1;j<=n;j++)
if(A[j][i]>A[r][i]) r=j;
for(int j=i;j<=n+1;j++) swap(A[i][j],A[r][j]);
if(fabs(A[i][i])<eps) continue;
for(int j=i+1;j<=n;j++){
db t=A[j][i]/A[i][i];
for(int k=i;k<=n+1;k++)
A[j][k]-=A[i][k]*t;
}
}
for(int i=n;i>0;i--){
for(int j=i+1;j<=n;j++)
A[i][n+1]-=A[i][j]*A[j][j];
if(A[i][i]==0) return false; //if A[i][n+1]=0:oo solutions else:no solution
A[i][i]=A[i][n+1]/A[i][i];
}
return true;
}
对质数取模版
把实数版的所有除法换位逆元即可
对合数取模版
不是所有数都对合数有逆元,因此在消元时无法直接乘上逆元;但消元的目的是将一方消为0,联想到辗转相除求gcd时最终也是将某个数变为了0,于是可以辗转相除消元。
然而代入求值时可能出bug,但在求行列式等操作中还是很可能出现的。放个消成上三角矩阵的代码。
bool Gauss(Mat A,int n){
for(int i=1;i<=n;i++){
int r=i;
for(int j=i+1;j<=n;j++)
if(A[j][i]>A[r][i]) r=j;
for(int j=i;j<=n+1;j++) swap(A[i][j],A[r][j]);
if(!A[i][i]) return false;
for(int j=i+1;j<=n;j++){//make A[j][i]=0
while(A[j][i]){ //b
int t=A[i][i]/A[j][i]; //(a,b)->(b,a%b)=(b,a-(a/b)*b)
for(int k=i;k<=n+1;k++){
A[i][k]=Minus(A[i][k],1ll*A[i][k]*t%P);
swap(A[i][k],A[j][k]);
}
}
}
}
return true;
}
线性基
在异或空间中常用的性质:一个线性空间中,极大线性无关子集的大小的一定的。
ll c[N];
void insert(ll x){
for(int i=50;i>=0;i--)
if((x>>i)&1){
if(!c[i]) { c[i]=x; return; }
x^=c[i];
}
}
矩阵求逆
矩阵 \(A\) 有逆的充要条件是:\(A\) 可通过线性变换变为单位矩阵。
推导: 若矩阵 \(B\) 满足 \(B\times [A|E]=[E|B]\) (\(E\) 为单位矩阵),则 $ B \times A =E$,即 \(B=A^{-1}\)
求法:对 \([A|E]\) 高斯消元,消成 \([E|B]\) 的形式(即将 \(A\) 消成 \(E\)),就得到 \(B\) 了。
小 \(trick\) :懒得回带?那就把所有除 \(A[i][i]\) 以外的 \(A[j][i]\) 都一次性消为0(操作上改下循环的起始位置即可)
bool Gauss_inv(Mat A,int n){
for(int i=1;i<=n;i++){
int r=i;
for(int j=i+1;j<=n;j++)
if(A[j][i]>A[r][i]) r=j;
for(int j=i;j<=2*n;j++) swap(A[i][j],A[r][j]);
if(!A[i][i]) return false;
int Inv=Pow_mod(A[i][i],P-2);
for(int j=1;j<=n;j++) { //trick: from 1->n all delete
if(j==i) continue;
int t=1ll*A[j][i]*Inv%P;
if(!t) continue;
for(int k=i;k<=n*2;k++)
A[j][k]=Minus(A[j][k],1ll*t*A[i][k]%P);
}
}
for(int i=1;i<=n;i++){
int Inv=Pow_mod(A[i][i],P-2);
for(int j=n+1;j<=n*2;j++)
A[i][j]=1ll*A[i][j]*Inv%P;
A[i][i]=1;
}
return true;
}
矩阵乘法 & 矩阵快速幂
太简单了就不说了吧。
矩阵行列式
终于知道定义了,但懒得写了。
一些性质:
1.将某一行 \(\times k\) 后加到另一行,行列式不变
2.交换某两行,行列式 \(\times = -1\)
3.某一行 \(\times k\),行列式 \(\times = k\)
4.把矩阵消成上三角or下三角矩阵后,行列式=对角线上所有数的乘积
代码中要注意的就是交换两行后记得 \(ret*=-1\)
既然选择了远方,便只顾风雨兼程