ACM矩阵基础入门

矩阵

定义

  顾名思义。就是由元素组成的矩形阵列。

表示

  一个 n n n m m m列的矩形阵列即是 n n n m m m列的矩阵,例如 2 2 2 3 3 3列的矩阵: ( a b c d e f ) \begin{pmatrix}a&b&c\\d&e&f\end{pmatrix} (adbecf) 在C++程序中可以使用二维数组表示矩阵。

struct Matrix
{
    int d[2][3];
};
零矩阵

  所有元素都为数0的矩阵称为零矩阵

n阶方阵

   n n n n n n列的矩阵称为 n n n阶方阵

上三角矩阵

  主对角线:n阶方阵的左上角与右下角之间的连线称为它的主对角线
   n n n阶方阵的主对角线下方的元素全为零的方阵称为上三角矩阵

下三角矩阵

   n n n阶方阵的主对角线上方的元素全为零的方阵称为下三角矩阵

单位元矩阵

  单位元矩阵:n阶方阵的主对角线上的值全是1,非主对角线上的值全是0。例如:3阶方阵
( 1 0 0 0 1 0 0 0 1 ) \begin{pmatrix}1&0&0\\0&1&0\\0&0&1\end{pmatrix} 100010001
单位元矩阵与任何矩阵相乘都等于原矩阵。
任何矩阵和单位元矩阵相乘都等于原矩阵。(两条不同)

邻接矩阵

  例题:各城市之间交通连接形成一个交通网络图。设图上有 n n n个城市构成的节(顶)点 v 1 v_1 v1 v 2 v_2 v2、···、 v n v_n vn,在每两个节点(城市)之间以线段相连接,这些线段可以是有向的,用箭头表示;也可以是无向的,因而可画出双箭头。这就形成了一个交通网络图,这样的图称为有向图(如果图上线段都是双向的,可以不画箭头,称为无向图),这个图可以用 n × n n×n n×n矩阵表示,这个矩阵叫做邻接矩阵,它的行和列分别表示这些节点的编号,行号表示出发节点(出度),列号表示到达节点(入度)。任何一条有向线段,在矩阵中用一个数值为1的元素表示,即若邻接矩阵 A = ( a i j ) n × n A=(a_{ij})_{n×n} A=(aij)n×n,则 a i j = { 1 , 节 点 v i 到 v j 有 箭 头 ( 不 含 中 间 节 点 ) 0 , 节 点 v i 到 v j 没 有 箭 头 a_{ij} = \begin{cases}1,节点v_i到v_j有箭头(不含中间节点)\\0,节点v_i到v_j没有箭头\end{cases} aij={1vivj()0vivj
例如图:在这里插入图片描述
邻接矩阵: v 1 v 2 v 3 v 4 v 5 v 1 0 1 0 0 0 v 2 0 0 1 0 0 v 3 0 1 0 1 1 v 4 1 0 0 0 0 v 5 1 1 0 1 0 \begin{matrix}&v_1&v_2&v_3&v_4&v_5\\v_1&0&1&0&0&0\\v_2&0&0&1&0&0\\v_3&0&1&0&1&1\\v_4&1&0&0&0&0\\v_5&1&1&0&1&0\end{matrix} v1v2v3v4v5v100011v210101v301000v400101v500100

矩阵的运算

加法

  矩阵加法首先满足两个矩阵的行和列一样,即都是 n n n m m m列的矩阵,相加结果也是 n n n m m m列的矩阵,即: A ( i , j ) + B ( i , j ) = ( A + B ) ( i , j ) A(i,j)+B(i,j)=(A+B)(i,j) A(i,j)+B(i,j)=(A+B)(i,j)
( 1 3 1 1 0 0 ) + ( 0 0 5 7 5 0 ) = ( 1 + 0 3 + 0 1 + 5 1 + 7 0 + 5 0 + 0 ) = ( 1 3 6 8 5 0 ) \begin{pmatrix}1&3&1\\1&0&0\end{pmatrix}+\begin{pmatrix}0&0&5\\7&5&0\end{pmatrix} = \begin{pmatrix}1+0&3+0&1+5\\1+7&0+5&0+0\end{pmatrix}=\begin{pmatrix}1&3&6\\8&5&0\end{pmatrix} (113010)+(070550)=(1+01+73+00+51+50+0)=(183560)

运算规则
  1. 满足交换律
    A + B = B + A A+B=B+A A+B=B+A
  2. 满足结合律
    ( A + B ) + C = A + ( B + C ) (A+B)+C=A+(B+C) (A+B)+C=A+(B+C)

减法

  矩阵减法首先满足两个矩阵的行和列一样,即都是 n n n m m m列的矩阵,相减结果也是 n n n m m m列的矩阵,即: A ( i , j ) − B ( i , j ) = ( A − B ) ( i , j ) A(i,j)-B(i,j)=(A-B)(i,j) A(i,j)B(i,j)=(AB)(i,j)
( 1 3 1 1 0 0 ) + ( 0 0 5 7 5 0 ) = ( 1 − 0 3 − 0 1 − 5 1 − 7 0 − 5 0 − 0 ) = ( 1 3 − 4 − 6 − 5 0 ) \begin{pmatrix}1&3&1\\1&0&0\end{pmatrix}+\begin{pmatrix}0&0&5\\7&5&0\end{pmatrix} = \begin{pmatrix}1-0&3-0&1-5\\1-7&0-5&0-0\end{pmatrix}=\begin{pmatrix}1&3&-4\\-6&-5&0\end{pmatrix} (113010)+(070550)=(101730051500)=(163540)

运算规则
  1. 满足交换律
    A + B = B + A A+B=B+A A+B=B+A
  2. 满足结合律
    ( A + B ) + C = A + ( B + C ) (A+B)+C=A+(B+C) (A+B)+C=A+(B+C)

数乘

  注意这里不是乘法,只是数乘,用一个数,去乘矩阵里的每一个数。 λ A ( i , j ) = λ A i j λA(i,j)=λA_{ij} λA(i,j)=λAij
5 ∗ ( 1 3 1 1 0 0 ) = ( 5 ∗ 1 5 ∗ 3 5 ∗ 1 5 ∗ 1 5 ∗ 0 5 ∗ 0 ) = ( 5 15 5 5 0 0 ) 5*\begin{pmatrix}1&3&1\\1&0&0\end{pmatrix}= \begin{pmatrix}5*1&5*3&5*1\\5*1&5*0&5*0\end{pmatrix}=\begin{pmatrix}5&15&5\\5&0&0\end{pmatrix} 5(113010)=(515153505150)=(5515050)

运算规则
  1. 满足结合律
    ( λ μ ) A = λ ( μ A ) (λμ)A=λ(μA) (λμ)A=λ(μA)
    ( λ + μ ) A = λ A + μ A (λ+μ)A=λA+μA (λ+μ)A=λA+μA
  2. 满足分配律
    λ ( A + B ) = λ A + λ B λ(A+B)=λA+λB λ(A+B)=λA+λB

乘法

  这个才是矩阵的重头戏。矩阵乘法中,两矩阵必须满足矩阵 A ( n a , m a ) A(n_a,m_a) A(na,ma)的列等于矩阵 B ( n b , m b ) B(n_b,m_b) B(nb,mb)的行。即 m a = n b m_a=n_b ma=nb。相乘的结果矩阵 C ( n c , m c ) C(n_c,m_c) C(nc,mc)中的行等于矩阵 A ( n a , m a ) A(n_a,m_a) A(na,ma)中的行,即 n c = n a n_c=n_a nc=na,矩阵 C ( n c , m c ) C(n_c,m_c) C(nc,mc)中的列等于矩阵 B ( n b , m b ) B(n_b,m_b) B(nb,mb)中的列,即 m c = m b m_c=m_b mc=mb
矩阵乘法的公式: C ( i , j ) = A ( i , 1 ) ∗ B ( 1 , j ) + A ( i , 2 ) ∗ B ( 2 , j ) + ⋅ ⋅ ⋅ + A ( i , m a ) ∗ B ( n b , j ) = ∑ k = 1 m a A ( i , k ) ∗ B ( k , j ) C(i,j) = A(i,1)*B(1,j)+A(i,2)*B(2,j)+···+A(i,m_a)*B(n_b,j) =\sum_{k=1}^{m_a}{A(i,k)*B(k,j)} C(i,j)=A(i,1)B(1,j)+A(i,2)B(2,j)++A(i,ma)B(nb,j)=k=1maA(i,k)B(k,j)
( 1 0 2 − 1 3 1 ) ∗ ( 3 1 2 1 1 0 ) = ( ( 1 ∗ 3 + 0 ∗ 2 + 2 ∗ 1 ) ( 1 ∗ 1 + 0 ∗ 1 + 2 ∗ 0 ) ( − 1 ∗ 3 + 3 ∗ 2 + 1 ∗ 1 ) ( − 1 ∗ 1 + 3 ∗ 1 + 1 ∗ 0 ) ) = ( 5 1 4 2 ) \begin{pmatrix}1&0&2\\-1&3&1\end{pmatrix}*\begin{pmatrix}3&1\\2&1\\1&0\end{pmatrix} = \begin{pmatrix}(1*3+0*2+2*1)&(1*1+0*1+2*0)\\(-1*3+3*2+1*1)&(-1*1+3*1+1*0)\end{pmatrix}=\begin{pmatrix}5&1\\4&2\end{pmatrix} (110321)321110=((13+02+21)(13+32+11)(11+01+20)(11+31+10))=(5412)

运算规则
  1. 满足结合律
    ( A B ) C = A ( B C ) (AB)C=A(BC) (AB)C=A(BC)
    ( λ A ) B = λ ( A B ) + A ( λ B ) (λA)B=λ(AB)+A(λB) (λA)B=λ(AB)+A(λB)
  2. 满足分配律
    A ( B ± C ) = A B ± A C A(B±C)=AB±AC A(B±C)=AB±AC(左分配律)
    ( B ± C ) A = B A ± C A (B±C)A=BA±CA (B±C)A=BA±CA(右分配律)

参考链接:http://www2.edu-edu.com.cn/lesson_crs78/self/j_0022/soft/ch0605.html

矩阵快速幂

我们已经学习过数字快速幂,例如: A k % m o d A^k\%mod Ak%mod
数字快速幂代码:

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;
}

矩阵快速幂和数字快速幂大致相同,只需要将 a n s 、 r e s ans、res ansres两个 L L LL 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] += (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;
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值