矩阵乘法
矩阵乘法
前言
矩阵乘法属于数论中的知识点,其实也就是新的概念,就像向量的运算一样,接受了之后就好了,当然可能会容易忘记,所以还是要多用多练。
基本概念
- 矩阵是一个按照长方阵列排列的复数或实数集合。
形如
矩阵就是多个数的集合。其中行数和列数相等(即
当两个矩阵的行数和列数分别相等时,这两个矩阵叫做同型矩形。
定义
矩阵乘法
- 前提:前一个矩阵的列数等于后一个矩阵的行数。
两个大小分别为
展开来:
如:
在计算时,我们要把行和列当做整体:
行 * 列,为行和列对应位置元素的乘积之和。
此外,对于单位矩阵
矩阵乘法满足结合律和分配律,但不满足交换律(元素位置会不同):
B2105 矩阵乘法
分析
基础题,按照定义来做,理解概念即可。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105;
int n,m,k,a[N][N],b[N][N],c[N][N];
int main ()
{
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=m;i++)
for(int j=1;j<=k;j++)
cin>>b[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
for(int l=1;l<=m;l++)
c[i][j]+=a[i][l]*b[l][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++) cout<<c[i][j]<<" ";
cout<<"\n";
}
return 0;
}
P3390 【模板】矩阵快速幂
分析
矩阵快速幂=矩阵乘法+快速幂。
由于矩阵乘法满足结合律,所以只需要将快速幂里的乘法改为矩阵乘法就可以了。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105,mod=1e9+7;
int n;
typedef vector<ll> vec;
typedef vector<vec> mat;//matrix
mat mul(mat a,mat b)
{
mat ans(a.size(),vec(b[0].size()));//行数为a的行数,列数为b的列数
for(int i=0;i<a.size();i++)
for(int j=0;j<b[0].size();j++)
{
for(int k=0;k<b[0].size();k++) ans[i][j]+=a[i][k]*b[k][j]%mod;
ans[i][j]%=mod;
}
return ans;
}
mat qmod(mat a,ll k)
{
mat ans(a.size(),vec(a.size()));
for(int i=0;i<n;i++) ans[i][i]=1;//初始化为单位矩阵
while(k)
{
if(k&1) ans=mul(ans,a);
a=mul(a,a);
k>>=1;
}
return ans;
}
int main()
{
ll k;
cin>>n>>k;
mat a(n,vec(n));
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>a[i][j];
mat ans=qmod(a,k);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++) cout<<ans[i][j]%mod<<" ";
cout<<"\n";
}
return 0;
}
P1939 矩阵加速(数列)
分析
可以看出
显然,
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105,mod=1e9+7;
int n;
typedef vector<ll> vec;
typedef vector<vec> mat;//matrix
mat mul(mat a,mat b)
{
mat ans(a.size(),vec(b[0].size()));//行数为a的行数,列数为b的列数
for(int i=0;i<a.size();i++)
for(int j=0;j<b[0].size();j++)
{
for(int k=0;k<b[0].size();k++) ans[i][j]+=a[i][k]*b[k][j]%mod;
ans[i][j]%=mod;
}
return ans;
}
mat qmod(mat a,ll k)
{
mat ans(a.size(),vec(a.size()));
for(int i=0;i<n;i++) ans[i][i]=1;
while(k)
{
if(k&1) ans=mul(ans,a);
a=mul(a,a);
k>>=1;
}
return ans;
}
int main()
{
ll k;
int t;
n=3;
cin>>t;
mat a(n,vec(n));
while(t--)
{
cin>>k;
if(k<=3)
{
cout<<1<<"\n";
continue;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=0;
a[0][0]=a[0][2]=a[1][0]=a[2][1]=1;
mat ans=qmod(a,k-1);
cout<<ans[0][0]<<"\n";
}
return 0;
}
P1962 斐波那契数列
分析
同P1939 矩阵加速(数列),求矩阵
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=105,mod=1e9+7;
int n;
typedef vector<ll> vec;
typedef vector<vec> mat;//matrix
mat mul(mat a,mat b)
{
mat ans(a.size(),vec(b[0].size()));//行数为a的行数,列数为b的列数
for(int i=0;i<a.size();i++)
for(int j=0;j<b[0].size();j++)
{
for(int k=0;k<b[0].size();k++) ans[i][j]+=a[i][k]*b[k][j]%mod;
ans[i][j]%=mod;
}
return ans;
}
mat qmod(mat a,ll k)
{
mat ans(a.size(),vec(a.size()));
for(int i=0;i<n;i++) ans[i][i]=1;
while(k)
{
if(k&1) ans=mul(ans,a);
a=mul(a,a);
k>>=1;
}
return ans;
}
int main()
{
ll k;
n=2;
cin>>k;
mat a(n,vec(n));
if(k<=2)
{
cout<<1<<"\n";
return 0;
}
a[0][0]=a[0][1]=a[1][0]=1;
mat ans=qmod(a,k-1);
cout<<ans[0][0]<<"\n";
return 0;
}
写起来挺累的 qwq。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」