「矩阵乘法与快速幂」学习笔记
矩阵乘法
-
定义:
给定矩阵
规模为 ,矩阵 规模为 ,定义 ,矩阵 规模为 ,满足:记住一个口诀:左行右列 。
-
注意:
对于矩阵乘法,满足乘法结合律和乘法分配律,不满足乘法交换律。
举个例子:
那么
可见
。 -
代码实现:
for(int i=1;i<=n;i++) for(int j=1;j<=p;j++) for(int k=1;k<=m;k++) c[i][j]=a[i][k]*b[k][j];
-
例题:
快速幂
-
定义:
在
的时间内求出 。 -
原理:
已知: 若
,则 。那么将
转化为二进制,举个例子:因为
有 个二进制位,所以在知道 前提下,即可在 的时间内求出 。问题转化位如何让求
,而在这个序列中,满足:于是就同样可以在
的时间内,求出 。得出结论:计算
,只需将 的二进制位为 的整系数幂乘起来即可。于是发现,上述所有步骤均可以在
的复杂度上递推实现。 -
代码实现:
-
计算
。int qpow(int a,int b) { int ans=1; for(;b;b>>=1) { if(b&1) ans*=a; a*=a; } return ans; } -
计算
int qpow(int a,int b,int P) { int ans=1; for(;b;b>>=1) { if(b&1) (ans*=a)%=P; (a*=a)%=P; } return ans; } -
根据费马小定理,
,前提, 为质数。那么当
为质数时,可通过 求出 ,即 的乘法逆元。可用快速幂实现。
-
矩阵快速幂
-
定义:
基于基本的快速幂,将乘法运算扩展为矩阵乘法运算。
由于矩阵乘法复杂度
,快速幂复杂度 ,所以矩阵快速幂复杂度为 ( 指矩阵规模, 指幂的次数)。 -
代码实现:
此处代码仅为样例,矩阵
规模均为 ,根据不同题的需要进行更改。导入概念,如果矩阵
对角线上元素均为 ,其余均为 ,则 。void qpow(int b) { memset(ans,0,sizeof(ans)); for(int i=1;i<=2;i++) ans[i][i]=1;//int ans=1; for(;b;b>>=1) { if(b&1) { for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) (c[i][j]+=(ans[k][j]*a[i][k])%P)%P; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) ans[i][j]=c[i][j],c[i][j]=0; }//if(b&1) ans*=a; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) (c[i][j]+=(a[i][k]*a[k][j])%P)%P; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) a[i][j]=c[i][j],c[i][j]=0;//a*=a; } } -
例题:
-
-
题意:
给定一个
,求 。 。 -
解法:
通过矩阵乘法,可将其转化为:
由此即可通过矩阵快速幂和矩阵乘法求出答案。
点击查看代码
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=10; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } int n,P,ans[N][N],c[N][N],a[N][N]; void qpow(int b) { for(;b;b>>=1) { if(b&1) { for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) (c[i][j]+=(ans[k][j]*a[i][k])%P)%P; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) ans[i][j]=c[i][j],c[i][j]=0; } for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) for(int k=1;k<=2;k++) (c[i][j]+=(a[i][k]*a[k][j])%P)%P; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) a[i][j]=c[i][j],c[i][j]=0; } } signed main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif read(n),read(P); a[1][1]=1; a[2][1]=1; a[1][2]=1; a[2][2]=0; for(int i=1;i<=2;i++) ans[i][i]=1; qpow(n-2); cout<<(ans[1][1]+ans[1][2])%P;//实则为 1*ans[1][1]+1*ans[1][2],1省去,参考矩阵乘法定义。 }
-
-
-
题意:
与上一道类似的,可理解为稍微变化的
第 项。给定一个
,求 。 。 -
解法:
也是和上面类似的,可以导出:
∵
∴
最后问题在于处理答案。
这次和上面的不同,上面的每一组就是
,而对于这次而言, 的结果不同,统计答案也不同。-
,对应矩阵中第一行,即 (因为 ,所以省去 “ ” ,下面不在解释) 。 -
,对应矩阵中第二行,即 。 -
,对应矩阵中第三行,即 。
点击查看代码
#include<bits/stdc++.h> #define int long long #define endl '\n' using namespace std; const int N=10,P=1e9+7; template<typename Tp> inline void read(Tp&x) { x=0;register bool z=true; register char c=getchar(); for(;c<'0'||c>'9';c=getchar()) if(c=='-') z=0; for(;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x=(z?x:~x+1); } int t,n,ans[N][N],c[N][N],a[N][N]; void qpow(int b) { for(;b;b>>=1) { if(b&1) { for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) (c[i][j]+=(ans[k][j]*a[i][k])%P)%P; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) ans[i][j]=c[i][j],c[i][j]=0; } for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) for(int k=1;k<=3;k++) (c[i][j]+=(a[i][k]*a[k][j])%P)%P; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) a[i][j]=c[i][j],c[i][j]=0; } } signed main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif read(t); while(t--) { read(n); a[1][1]=2,a[1][2]=1,a[1][3]=1; a[2][1]=1,a[2][2]=1,a[2][3]=1; a[3][1]=1,a[3][2]=0,a[3][3]=1; memset(ans,0,sizeof(ans)); for(int i=1;i<=3;i++) ans[i][i]=1; qpow((n-1)/3); if(n%3==0) cout<<(ans[1][1]+ans[1][2]+ans[1][3])%P<<endl; else if(n%3==2) cout<<(ans[2][1]+ans[2][2]+ans[2][3])%P<<endl; else if(n%3==1) cout<<(ans[3][1]+ans[3][2]+ans[3][3])%P<<endl; } } -
-
-
序言
写于
后面(甚至前面)好多只是都要用到矩阵乘法与矩阵快速幂,所以就来补了。
顺便回顾一下快速幂,
题还没有打完,但是知识点算是搞明白了,加深一下记忆继续打题,以防下面的题不知所措。
例题
后续打的题目如果写了题解就放题解链接,否则放题目链接。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探