hhhh 我复活了!!
最近学了亿一点点东西
慢慢来写吧
先来记录一下矩阵
定义 & 矩阵乘法 & 初等变换
矩阵
在线性代数中分为 行向量
与 列向量
From OI-wiki …
线性代数的主要研究对象是列向量,约定使用粗体小写字母表示列向量.在用到大量向量与矩阵的线性代数中,不引起混淆的情况下,在手写时,字母上方的向量记号可以省略不写.
向量也是特殊的矩阵.如果想要表示行向量,需要在粗体小写字母右上方写转置记号.行向量在线性代数中一般表示方程.
对于矩阵 $A$ ,主对角线指所有 $A_{i,i}$ 的元素
单位矩阵
一般以 $I$ 表示单位矩阵,形式为:
对角矩阵
对角矩阵
也可以表示为
同型矩阵
两个矩阵,行数与列数对应相同,称为同型矩阵。
方阵
行数等于列数的矩阵称为方阵.方阵是一种特殊的矩阵.对于”$n$ 阶矩阵”的习惯表述,实际上讲的是 $n$ 阶方阵.阶数相同的方阵为同型矩阵。
研究方程组、向量组、矩阵的秩的时候,使用一般的矩阵.研究特征值和特征向量、二次型的时候,使用方阵。
三角矩阵
如果方阵主对角线左下方的元素均为 ,称为上三角矩阵.如果方阵主对角线右上方的元素均为 ,称为下三角矩阵.
两个上(下)三角矩阵的乘积仍然是上(下)三角矩阵.如果对角线元素均非 0,则上(下)三角矩阵可逆,逆也是上(下)三角矩阵.
单位三角矩阵
如果上三角矩阵 的对角线全为 ,则称 是单位上三角矩阵.如果下三角矩阵 的对角线全为 ,则称 是单位下三角矩阵.
两个单位上(下)三角矩阵的乘积仍然是单位上(下)三角矩阵,单位上(下)三角矩阵的逆也是单位上(下)三角矩阵.
矩阵乘法
矩阵乘法是 向量内积 的推广。
矩阵相乘只有在第一个矩阵行数等于第二个矩阵的列数是才有意义。
设 为 的矩阵, 为 的矩阵。
设 ,则 为 的矩阵。
其中 的第 行第 列的元素 表示为:
容易证明,矩阵乘法不满足一般的交换律,满足结合律。
初等矩阵
倍乘矩阵
倍乘矩阵是一种特殊的对角矩阵。
其中第 个元素为
特别的,当时,
对换矩阵
对换矩阵是一种特殊的的对称矩阵。
对换矩阵主对角线上除了第 个元素和第 个元素都为 ,第 个元素和第 个元素为 ,而在第 行第 列和第 行第 列为 ,其余位置为 。
对换矩阵要求 与 不能相等.
倍加矩阵
倍加矩阵是在单位阵 的基础上,令第 行第 列为 。
倍加矩阵要求 。
倍加矩阵是一种上三角矩阵或者下三角矩阵.
初等变换
不仅限于方阵,对于一般的矩阵 ,可以进行初等行变换和初等列变换,统称为初等变换。
初等行变换与初等列变换一样,都有 3 种:
- 倍乘(multiplication)
- 对换(switching)
- 倍加(addition)
这里先介绍初等行变换:
- 第 𝑖 行乘非零数 :
- 第 𝑖,𝑗 行互换:
- 第 𝑗 行乘 𝑘 加到第 𝑖 行:
将上述操作的行改为列,即得到初等列变换。
From OI-wiki…
在初等变换中,对换可以通过倍乘和倍加实现。显然,倍加不能通过倍乘和对换实现。借助行列式的知识,以及下文的初等变换与矩阵乘法的等价性,也能说明倍乘不能通过倍加和对换实现。
因此,相较对换而言,倍乘和倍加是更为本质的操作。对换操作是为了在消元法中,保证消元的有序,而引入的辅助操作。
矩阵快速幂
对于矩阵 ,显然 中 可以被拆分成唯一分解 ,其中 且
所以对于所有不为 的 的 的集合 ,
容易发现,这正是快速幂。
故我们可以用快速幂加速矩阵幂运算
//hanser!!!!!!!
#include<bits/stdc++.h>
using namespace std;
#define intc constexpr int
#define int long long
#define Cios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
intc mod=1e9+7;
intc N=200;
class Matrix {
public:
int line,col;
int c[N][N];
Matrix ()=default;
Matrix (int n,int m):line(n),col(m) {
memset (c,0,sizeof c);
}
static Matrix unit (int n) {
Matrix m=Matrix(n,n);
for (int i=1;i<=n;i++) m.c[i][i]=1;
return m;
}
int * operator [] (const int pos) {
return c[pos];
}
Matrix operator * (Matrix &q) {
Matrix ans=Matrix(line,q.col);
for (int i=1;i<=ans.line;i++) {
for (int j=1;j<=ans.col;j++) {
for (int k=1;k<=col;k++) ans[i][j]=(ans[i][j]+c[i][k]*q[k][j])%mod;
}
}
return ans;
}
Matrix pow (int b) {
Matrix res=Matrix::unit(line),a=*this;
if (b<=0) return res;
while (b) {
if (b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
};
int n,k;
signed main() {
cin>>n>>k;
Matrix mx=Matrix(n,n);
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) cin>>mx[i][j];
}
mx=mx.pow(k);
for (int i=1;i<=n;i++) {
for (int j=1;j<=n;j++) cout<<mx[i][j]<<" ";
cout<<"\n";
}
return 0;
}
评论(1)