首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

矩阵基础运算

  • 25-01-18 13:02
  • 4694
  • 10670
blog.csdn.net

矩阵的加减法和数乘为线性运算,均为逐个元素进行运算。

形式化地,即 A   o p   B = A i , j   o p   B i , j A\space op\space B=A_{i,j}\space op\space B_{i,j} A op B=Ai,j​ op Bi,j​, o p op op 为 + / − +/- +/−。

矩阵乘法要求两个矩阵的行数和列数相等,设 A A A 为 P × M P\times M P×M 的矩阵, B B B 为 M × Q M\times Q M×Q 的矩阵,则 C = A × B , C i , j = ∑ k = 1 M A i , k × B k , j C=A\times B,C_{i,j}=\sum_{k=1}^{M}A_{i,k}\times B_{k,j} C=A×B,Ci,j​=∑k=1M​Ai,k​×Bk,j​。即矩阵 A A A 第 i i i 行 M M M 个数与矩阵 B B B 第 j j j 列 M M M 个数分别相乘再相加得到的,如下图。
为了方便进行运算,我们会把矩阵设为二维数组,放在结构体里面,并重载运算符。
这是我的矩阵加减乘法的模版。

struct matrix{
	int a[N][N];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator +(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]+T.a[i][j])%mod;
		return res;
	}
	matrix operator -(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]-T.a[i][j])%mod;
		return res;
	}
	matrix operator *(const matrix& T) const{
		matrix res;//这个写法常数会小一些
		for(int i=1;i<N;i++){
			for(int k=1;k<N;k++){
				int r=a[i][k];
				for(int j=1;j<N;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j])%mod;
			}
		}
		return res;
	}
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

由于矩阵也有乘法,那自然也有矩阵的快速幂,写法与普通快速幂同理。
附洛谷矩阵快速幂模版代码:

#include
using namespace std;
#define int long long
#define rd read()
const int N=110,mod=1e9+7;
int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int n,k;
struct matrix{
	int a[N][N];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator +(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]+T.a[i][j])%mod;
		return res;
	}
	matrix operator -(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++)
			for(int j=1;j<N;j++)
				res.a[i][j]=(a[i][j]-T.a[i][j])%mod;
		return res;
	}
	matrix operator *(const matrix& T) const{
		matrix res;
		for(int i=1;i<N;i++){
			for(int k=1;k<N;k++){
				int r=a[i][k];
				for(int j=1;j<N;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j])%mod;
			}
		}
		return res;
	}
}M;
signed main(){
	n=rd,k=rd;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) M.a[i][j]=rd;
	matrix res;
	for(int i=1;i<=n;i++) res.a[i][i]=1;//res要初始化为单位矩阵,即单位矩阵*M^K
	while(k){
		if(k&1) res=res*M;
		M=M*M,k>>=1;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++) cout<<res.a[i][j]<<" ";
		cout<<"\n";
	}
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

而矩阵乘法的运用很多,最常用的便是加速递推,可以用其优化 dp(例如动态 dp)等等。最经典的便是斐波那契数列的应用,首先把原线性递推式转化为矩阵,然后用矩阵快速幂即可解决。

#include
using namespace std;
#define ll long long
#define rd read()
ll read(){
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int mod=1e9+7;ll n;
struct matrix{
	ll a[10][10];
	matrix(){memset(a,0,sizeof(a));}
	matrix operator *(const matrix& T)const{
		matrix res;
		for(int i=1;i<=2;i++){
			for(int k=1;k<=2;k++){
				ll r=a[i][k];
				for(int j=1;j<=2;j++)
					res.a[i][j]=(res.a[i][j]+1ll*r*T.a[k][j]%mod)%mod;
			}
		}
		return res;
	}
}bas,ans;
int main(){
	n=rd;ll x=n-2;
	if(n<=2){puts("1");return 0;}
	ans.a[1][1]=ans.a[1][2]=1;
	bas.a[1][1]=bas.a[1][2]=bas.a[2][1]=1;
	while(x){
		if(x&1) ans=ans*bas;
		bas=bas*bas,x>>=1;
	}
	printf("%lld\n",ans.a[1][1]%mod);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

再来一道(P1939 矩阵加速(数列))

考虑 [ a i a i − 1 a i − 2 ]

[aiai−1ai−2][aiai−1ai−2]
[ai​​ai−1​​ai−2​​] 如何变为 [ a i + 1 a i a i − 1 ]
[ai+1aiai−1][ai+1aiai−1]
[ai+1​​ai​​ai−1​​]
,这道题非常显然。

[ a i + 1 a i a i − 1 ] × [ 1 1 0 0 0 1 1 0 0 ]

[ai+1aiai−1][ai+1aiai−1]
\times
⎡⎣⎢101100010⎤⎦⎥[110001100]
[ai+1​​ai​​ai−1​​]× ​101​100​010​ ​。然后套个矩阵加速幂就可以了。

注:本文转载自blog.csdn.net的summ1ts的文章"https://blog.csdn.net/summ1ts/article/details/142969032"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

137
数学
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top