对于矩阵快速幂,其作用能够达到快速递推公式的作用
这里先定义一个矩阵
struct martix{ int x[105][105]; martix(){memset(x,0,sizeof x);} };
首先看如何进行矩阵计算,由线性代数知:
martix cacl(martix a,martix b){ martix c; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) c.x[i][j]=(c.x[i][j]%mod+a.x[i][k]%mod*b.x[k][j]%mod)%mod; return c; }
那么如何快速求出 $k$ 个矩阵的相乘呢? 我们可以回忆数字的快速幂,普通的快速幂是把 $k$ 化成二进制,即
int qpow(int a,int k){ int res=1;; while(k){ if(k&1) res*=a,res%=mod; k>>=1,a*=a,a%=mod; } return res; }
矩阵快速幂与其类似,也就把次方数进行二进制计算
martix qpow(martix mp,int k){ martix res; for(int i=1;i<=n;i++) res.x[i][i]=1; while(k){ if(k&1) res=cacl(mp,res); k>>=1,mp=cacl(mp,mp); } return res; }
模板:
#include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; int n,k; struct martix{ int x[105][105]; martix(){memset(x,0,sizeof x);} }; martix cacl(martix a,martix b){ martix c; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) c.x[i][j]=(c.x[i][j]%mod+a.x[i][k]%mod*b.x[k][j]%mod)%mod; return c; } martix qpow(martix mp,int k){ martix res; for(int i=1;i<=n;i++) res.x[i][i]=1; while(k){ if(k&1) res=cacl(mp,res); k>>=1,mp=cacl(mp,mp); } return res; } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>k; martix mp; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>mp.x[i][j]; martix res=qpow(mp,k); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) cout<<res.x[i][j]%mod<<' '; cout<<endl; } return 0; }
矩阵快速幂的应用: 【朝夕的ACM笔记】杂项-矩阵快速幂 - 知乎 (zhihu.com)
标签:martix,int,res,矩阵,mp,快速 From: https://www.cnblogs.com/o-Sakurajimamai-o/p/18050422