矩阵
定义
顾名思义。就是由元素组成的矩形阵列。
表示
一个 行 列的矩形阵列即是 行 列的矩阵,例如 行 列的矩阵: 在C++程序中可以使用二维数组表示矩阵。
struct Matrix
{
int d[2][3];
};
零矩阵
所有元素都为数0的矩阵称为零矩阵。
n阶方阵
行 列的矩阵称为 阶方阵 。
上三角矩阵
主对角线:n阶方阵的左上角与右下角之间的连线称为它的主对角线。
阶方阵的主对角线下方的元素全为零的方阵称为上三角矩阵。
下三角矩阵
阶方阵的主对角线上方的元素全为零的方阵称为下三角矩阵。
单位元矩阵
单位元矩阵:n阶方阵的主对角线上的值全是1,非主对角线上的值全是0。例如:3阶方阵
单位元矩阵与任何矩阵相乘都等于原矩阵。
任何矩阵和单位元矩阵相乘都等于原矩阵。(两条不同)
邻接矩阵
例题:各城市之间交通连接形成一个交通网络图。设图上有
个城市构成的节(顶)点
、
、···、
,在每两个节点(城市)之间以线段相连接,这些线段可以是有向的,用箭头表示;也可以是无向的,因而可画出双箭头。这就形成了一个交通网络图,这样的图称为有向图(如果图上线段都是双向的,可以不画箭头,称为无向图),这个图可以用
矩阵表示,这个矩阵叫做邻接矩阵,它的行和列分别表示这些节点的编号,行号表示出发节点(出度),列号表示到达节点(入度)。任何一条有向线段,在矩阵中用一个数值为1的元素表示,即若邻接矩阵
,则
例如图:
邻接矩阵:
矩阵的运算
加法
矩阵加法首先满足两个矩阵的行和列一样,即都是
行
列的矩阵,相加结果也是
行
列的矩阵,即:
。
运算规则
- 满足交换律
- 满足结合律
减法
矩阵减法首先满足两个矩阵的行和列一样,即都是
行
列的矩阵,相减结果也是
行
列的矩阵,即:
。
运算规则
- 满足交换律
- 满足结合律
数乘
注意这里不是乘法,只是数乘,用一个数,去乘矩阵里的每一个数。
运算规则
- 满足结合律
- 满足分配律
乘法
这个才是矩阵的重头戏。矩阵乘法中,两矩阵必须满足矩阵
的列等于矩阵
的行。即
。相乘的结果矩阵
中的行等于矩阵
中的行,即
,矩阵
中的列等于矩阵
中的列,即
。
矩阵乘法的公式:
运算规则
- 满足结合律
- 满足分配律
(左分配律)
(右分配律)
参考链接:http://www2.edu-edu.com.cn/lesson_crs78/self/j_0022/soft/ch0605.html
矩阵快速幂
我们已经学习过数字快速幂,例如:
。
数字快速幂代码:
typedef long long LL;//为long long重命名
LL ppow(LL n, LL k)
{
LL res = n;
LL ans = 1;
while(k)
{
if(k&1) ans = ans*res;
res = res*res;
k >>= 1;
}
return ans;
}
矩阵快速幂和数字快速幂大致相同,只需要将 两个 类型的整数改成矩阵就可以了。
const int m_max = 15;
struct Matrix
{
int d[m_max][m_max];
};
int m_size;
Matrix matrix_mul(Matrix a, Matrix b)
{
Matrix ans;
for(int i = 0; i < m_size; i++)
for(int j = 0; j < m_size; j++)
{
ans.d[i][j] = 0;
for(int k = 0; k < m_size; k++)
{
ans.d[i][j] += (a.d[i][k]*b.d[k][j]);
}
}
return ans;
}
Matrix init()//把矩阵初始化单位元矩阵
{
Matrix ans;
for(int i = 0; i < m_size; i++)
for(int j = 0; j < m_size; j++)
ans.d[i][j] = i==j?1:0;
return ans;
}
Matrix ppow(Matrix a,int k)
{
Matrix ans = init();
Matrix res = a;
while(k)
{
if(k&1)
ans = matrix_mul(ans, res);
res = matrix_mul(res, res);
k >>= 1;
}
return ans;
}
第二十四天训练学习A题解
题目链接:A:Tr A
题解:板子题,题意很明确。
代码:
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
const int mod = 200907;
typedef long long LL;
const int m_max = 15;
struct Matrix
{
int d[m_max][m_max];
};
int m_size;
Matrix matrix_mul(Matrix a, Matrix b)
{
Matrix ans;
for(int i = 0; i < m_size; i++)
for(int j = 0; j < m_size; j++)
{
ans.d[i][j] = 0;
for(int k = 0; k < m_size; k++)
{
ans.d[i][j] = (ans.d[i][j]+a.d[i][k]*b.d[k][j])%9973;
}
}
return ans;
}
Matrix init()//把矩阵初始化单位元矩阵
{
Matrix ans;
for(int i = 0; i < m_size; i++)
for(int j = 0; j < m_size; j++)
ans.d[i][j] = i==j?1:0;
return ans;
}
Matrix ppow(Matrix a,int k)
{
Matrix ans = init();
Matrix res = a;
while(k)
{
if(k&1)
ans = matrix_mul(ans, res);
res = matrix_mul(res, res);
k >>= 1;
}
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int k;
Matrix a;
scanf("%d%d", &m_size, &k);
for(int i = 0; i < m_size; i++)
{
for(int j = 0; j < m_size; j++)
{
scanf("%d", &a.d[i][j]);
}
}
Matrix ans = ppow(a,k);
int sum = 0;
for(int i = 0; i < m_size; i++)
{
sum += ans.d[i][i];
}
printf("%d\n", sum%9973);
}
return 0;
}