文章目录

  • 矩阵概念
    • 什么是矩阵
    • 特殊矩阵(单位矩阵)
    • 矩阵运算
      • 矩阵乘法
  • 矩阵快速幂代码C++实现
    • 代码分解
      • 输入输出矩阵的函数
      • 矩阵相乘
      • 构造单位矩阵函数
      • 矩阵快速幂实现函数
      • 快速幂模板代码
  • 矩阵快速幂应用
    • 经典题目

矩阵概念

什么是矩阵

在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合

特殊矩阵(单位矩阵)

单位矩阵之所以是特殊矩阵是因为单位矩阵的主对角线上全是1,其他元素全为0,用单位矩阵乘以任何矩阵都将得到原矩阵,类似数字1的效果。
下面是一个3x3的单位矩阵

矩阵运算

矩阵加法减法比较简单这里就不过多介绍了,主要说一下矩阵乘法,

矩阵乘法

矩阵相乘只有在第一个矩阵的列数(column)和第二个矩阵的行数(row)相同时才有意义,设A为m x p 的矩阵,B为p x n 的矩阵,那么称m x n的矩阵C为矩阵A与B的乘积 ,其中矩阵C中的第 行第 列元素可以表示为


矩阵是满组结合律的,而就是因为矩阵满足了结合律,所以矩阵乘法可以使用快速幂算法,快速幂算法中我们把一个数连续乘的问题利用结合律简化,使运算循环次数减少,例如:计算35,原本要计算的是3 x 3 x 3 x 3 x 3,但是用结合律简化得(3 x 3)x (3 x 3)x 3进而得9 x 9 x 3 继续使用结合律(9 x 9)x 3 最后得81 x 3,把需要五次累乘问题转换成了一次累乘问题,在幂次小的时候没多少区别,但是幂次大的时候差距会非常明显后者更有效率,关于快速幂思想就不再过多说了,对此不明白的同学可以参考参考专门写的一篇快速幂的博客,那里写的很详细点我传送。矩阵因为有结合律也可以用次方法简化,例如M是一个矩阵现在要求M7。传统方法是七次连续乘M也就是MxMxMxMxMxMxM 。但根据快速幂思想加上矩阵支持结合律可以这样写(MxM)x(MxM)x(MxM)xM也就是求M2的3次方然后再乘以一个M得M2 x M2 x M2 x M我们可以继续用结合律(M2 x M2 )x M2 x M得M4x M2 x M,这就是快速幂思想在矩阵上的运用。矩阵快速幂的实现代码其实就是基于快速幂代码模板的。
矩阵快速幂样例代码

矩阵快速幂代码C++实现

#include<iostream>using namespace std;const int MAX = 15;
const int MOD = 9973;struct Matrix
{int mat[MAX][MAX];
};Matrix create_identity_matrix(Matrix E, int n);       //构造单位矩阵
Matrix mat_mul(Matrix a, Matrix b, int n);          //矩阵相乘
Matrix quick_power(Matrix basic, int power, int n); //矩阵快速幂
void input_mat(Matrix* p, int n, int m);            //输入矩阵
void print_marrix(Matrix a, int n, int m);          //打印矩阵int main(void)
{Matrix mat_now;Matrix ans_now;int n, k;//n是矩阵的行列数, k是幂次数cin >> n >> k;input_mat(&mat_now, n, n);ans_now = quick_power(mat_now, k, n);print_marrix(ans_now, n, n);return 0;
}Matrix create_identity_matrix(Matrix E, int n)
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (i == j)E.mat[i][j] = 1;elseE.mat[i][j] = 0;return E;
}Matrix mat_mul(Matrix a, Matrix b, int n)
{Matrix ans;memset(ans.mat, 0, sizeof(ans.mat));//这里会看出三次循环顺序是i,k,j而不是说i,j,k,当然i, j, k也对//不过矩阵在计算机内存里是线性存储的所有i,k,j更快//也就是说i,j,k顺序计算适合人类计算而i,k,j更适合计算机计算for (int i = 0; i < n; i++)for (int k = 0; k < n; k++)for (int j = 0; j < n; j++){ans.mat[i][j] += a.mat[i][k] * b.mat[k][j];ans.mat[i][j] %= MOD;//ans.mat[i][j] += a.mat[i][k] * b.mat[k][j] % MOD;}return ans;
}Matrix quick_power(Matrix basic, int power, int n)
{Matrix result;//下面这一行本质上没有意义//但是vs2019会以为你调用了未初始化变量然后报错//当然这个机制可以在设置关闭,如果没有关闭的话加上下面这一行不然无法通过编译memset(result.mat, 0, sizeof(result.mat));result = create_identity_matrix(result, n);    //初始化为单位矩阵while (power > 0){if (power & 1)result = mat_mul(result, basic, n);basic = mat_mul(basic, basic, n);power >>= 1;}return result;
}void input_mat(Matrix* p, int n, int m)
{for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> p->mat[i][j];
}void print_marrix(Matrix a, int n, int m)
{for (int i = 0; i < n; i++){for (int j = 0; j < m; j++)cout << ' ' << a.mat[i][j];cout << endl;}
}

代码分解

输入输出矩阵的函数

这个函数利用两个for循环输入与打印矩阵的。

void input_mat(Matrix* p, int n, int m)      //输入函数
{for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> p->mat[i][j];
}void print_marrix(Matrix a, int n, int m)  //输出函数
{for (int i = 0; i < n; i++){for (int j = 0; j < m; j++)cout << ' ' << a.mat[i][j];cout << endl;}
}

矩阵相乘

因为矩阵乘法无法用内部的 * 运算符计算乘法,所有我们用函数实现相乘,注意里面实现取余操作的位置与方法。

Matrix mat_mul(Matrix a, Matrix b, int n)
{Matrix ans;memset(ans.mat, 0, sizeof(ans.mat));//这里会看出三次循环顺序是i,k,j而不是说i,j,k,当然i, j, k也对//不过矩阵在计算机内存里是线性存储的所有i,k,j更快//也就是说i,j,k顺序计算适合人类计算而i,k,j更适合计算机计算for (int i = 0; i < n; i++)for (int k = 0; k < n; k++)for (int j = 0; j < n; j++){ans.mat[i][j] += a.mat[i][k] * b.mat[k][j];ans.mat[i][j] %= MOD;//快速幂中常常带有取余某个数的要求,在矩阵快速幂中这个取余需要放在乘法函数里//ans.mat[i][j] += a.mat[i][k] * b.mat[k][j] % MOD;}return ans;
}

构造单位矩阵函数

在快速幂中我们需要把存储答案的变量初始化为1,但是矩阵快速幂中不能是1因为矩阵不可以。代替1的是单位矩阵,我们要把存储答案的变量初始化为单位矩阵。

Matrix create_identity_matrix(Matrix E, int n)
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)if (i == j)E.mat[i][j] = 1;elseE.mat[i][j] = 0;return E;
}

矩阵快速幂实现函数

矩阵快速幂函数实现模板其实就是快速幂模板可以和快速幂模板代码做对比查看理解

Matrix quick_power(Matrix basic, int power, int n)
{Matrix result;//下面这一行本质上没有意义//但是vs2019会以为你调用了未初始化变量然后报错//当然这个机制可以在设置关闭,如果没有关闭的话加上下面这一行不然无法通过编译memset(result.mat, 0, sizeof(result.mat));result = create_identity_matrix(result, n);    //初始化为单位矩阵while (power > 0){if (power & 1)result = mat_mul(result, basic, n);basic = mat_mul(basic, basic, n);power >>= 1;}return result;
}

快速幂模板代码

long long int quik_power(int base, int power, int p)
{long long int result = 1;   while (power > 0)           {if (power & 1)                                    result = result * base % p;   base = base * base % p ;                            power >>= 1;                                 }return result % p;
}

矩阵快速幂应用

经典题目

题目HDOJ 1575 Tr A
题解 HDOJ 1575 Tr A 题解

矩阵快速幂 超详细介绍相关推荐

  1. 43行代码AC_HDU-2604 Queuing(矩阵快速幂,附详细的知识讲解、模板例题)

    一道经典的矩阵快速幂模板题. 传送门1-->快速幂基本思想 传送门2-->矩阵快速幂讲解(教主传授) 传送门3.1-->HDU-1575(经典矩阵快速幂模板题1) 传送门3.2--& ...

  2. 【目标检测】56、目标检测超详细介绍 | Anchor-free/Anchor-based/Backbone/Neck/Label-Assignment/NMS/数据增强

    文章目录 1.双阶段和单阶段目标检测器 1.1 双阶段目标检测器 1.1.1 R-CNN 1.1.2 SPP 1.1.3 Fast R-CNN 1.1.4 Faster R-CNN 1.2 单阶段目标 ...

  3. 一文彻底搞懂快速幂(原理、实现、矩阵快速幂)

    前言 大家好,我是bigsai,之前有个小老弟问到一个剑指offer一道相关快速幂的题,这里梳理一下讲一下快速幂! 快速幂是什么? 顾名思义,快速幂就是快速算底数的n次幂.你可能疑问,求n次幂算n次叠 ...

  4. 快速幂或者矩阵快速幂

    快速幂或者矩阵快速幂在算大指数次方时是很高效的,他的基本原理是二进制,下面的A可以是一个数也可以是一个矩阵(本文特指方阵),若是数就是快速幂算法,若是矩阵就是矩阵快速幂算法,用c++只需把矩阵设成一个 ...

  5. 卷积神经网络超详细介绍

    文章目录 1.卷积神经网络的概念 2. 发展过程 3.如何利用CNN实现图像识别的任务 4.CNN的特征 5.CNN的求解 6.卷积神经网络注意事项 7.CNN发展综合介绍 8.LeNet-5结构分析 ...

  6. 卷积神经网络(CNN)超详细介绍

    文章转自:https://blog.csdn.net/jiaoyangwm/article/details/80011656 文章目录 1.卷积神经网络的概念 2. 发展过程 3.如何利用CNN实现图 ...

  7. 卷积神经网络超详细介绍1

    1.卷积神经网络的概念 2. 发展过程 3.如何利用CNN实现图像识别的任务 4.CNN的特征 5.CNN的求解 6.卷积神经网络注意事项 7.CNN发展综合介绍 8.LeNet-5结构分析 9.Al ...

  8. 卷积神经网络超详细介绍(转载)

    卷积神经网络超详细介绍 文章目录 1.卷积神经网络的概念 2. 发展过程 3.如何利用CNN实现图像识别的任务 4.CNN的特征 5.CNN的求解 6.卷积神经网络注意事项 7.CNN发展综合介绍 8 ...

  9. 矩阵快速幂以及其优化【华东交大课程】

    矩阵快速幂以及其优化[华东交大课程] 快速幂基础:C++快速幂_Kicamon的博客-CSDN博客 矩阵快速幂就是在快速幂的基础上结合矩阵运算的用法,其用途较为广泛,可以很大程度上优化代码. 一.矩阵 ...

  10. 【语义分割】1、语义分割超详细介绍

    文章目录 一.分割方法介绍 1.1 Fully Convolutional Networks [2015] 1.1.1 FCN 1.1.2 ParseNet 1.2 Encoder-Decoder B ...

最新文章

  1. ORACLE分区表删除分区数据
  2. mui汉字图标_MUI从入门到项目实战(三)增加自定义icon图标
  3. 高并发IM系统架构优化实践
  4. VC++ 创建Windows服务
  5. pythonalert弹窗_python+selenium八:Alert弹窗
  6. 置信学习:让样本中的“脏数据“原形毕露
  7. spring mvc学习(19):cookievalue注解(显示cookie的值,默认必须有值)
  8. synchronized原理_synchronized 关键字底层原理
  9. html美甲预约网页制作,教程.html · NFS1077/FNM美甲店 - Gitee.com
  10. qt 实现拖动矩形角度_Qt 绘图之图形视图框架
  11. 敏捷开发“松结对编程”系列之八:微软 Tech ed2011 自组织团队与松结对编程讲稿(敏捷开发)...
  12. 【优化算法】饥饿游戏搜索算法(HGS)【含Matlab源码 1802期】
  13. EAS BOS 介绍
  14. 百度地图怎么不显示服务器地址,百度地图使用指南
  15. 查看kms服务器信息,查看kms服务器地址
  16. tukey 窗口_C语言完成窗口算法
  17. 【微信小程序】快进来弹钢琴啦~钢琴小程序源码分享
  18. 轻松易懂的CSS学习权威指南来了
  19. 使用音频分析工具audacity分析wave文件
  20. Jenkins基础:获取Jenkins-Crumb的错误信息与对应方法

热门文章

  1. C++中 sprintf函数的用法
  2. C# ajax上传图片
  3. 计算机版本低怎么升级,电脑ie浏览器版本过低怎么升级(浏览器版本过低升级步骤)...
  4. artset下载_artset绘画软件下载
  5. javamail 超时_为什么JavaMail连接超时过长
  6. 城管系统服务器,数字城管系统建设方案详细.doc
  7. linux设置ipsan_Linux下IP SAN共享存储操作记录
  8. 计算机传真,电脑收发传真
  9. NOIP2016提高组 day1
  10. 有C++特色的极乐净土