P3390 【模板】矩阵快速幂

P3390 【模板】矩阵快速幂

本来想学动态dp 然后被一路 递归 到了这里。

首先我们要知道矩阵乘法是什么,两个矩阵可以 A,B 可以相乘,当且仅当 A 的列数= B的行数

两个大小分别为 m×nn×p 的矩阵 A,B 相乘的结果为一个大小为 m×p 的矩阵。将结果矩阵记作 C,则

cij=k=1naikbkj,\qquad(1im1jp).

其实按我的理解就是将 A 的某一行 i 整体取下来然后向下旋转 90°,然后找到第 j 列,将这两个数列 按位相乘 之后求和作为 Ci,j 好了我知道这很不严谨 qwq

然后我们都学过快速幂对吧,直接乘就完事了

Code:

#include<bits/stdc++.h>
#define int long long
const int N=105;
const int mod=1e9+7;
using namespace std;
int n,k;
struct Matrix{
int a[N][N];
}ANS;
Matrix operator *(const Matrix &A,const Matrix &B)
{
Matrix res={{0}};
for(int i=1;i<=n;i++)for(int k=1;k<=n;k++)for(int j=1;j<=n;j++)
{
res.a[i][j]+=A.a[i][k]*B.a[k][j];
res.a[i][j]%=mod;
}
return res;
}
Matrix qpow(Matrix x,int k)
{
Matrix K=x;
if(k<0){for(int i=1;i<=n;i++)x.a[i][i]=1;return x;}
while(k)
{
if(k&1)
{
x=x*K;
}
K=K*K;
k>>=1;
}
return x;
}
void work()
{
cin>>n>>k;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
{
scanf("%lld",&ANS.a[i][j]);
}
//cout<<n<<" "<<k<<"\n";
//return ;
if(k)
ANS=qpow(ANS,k-1);
else
{
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
{
cout<<(i==j ? 1 : 0)<<(j==n ? "\n" : " ");
}
return ;
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
{
printf("%lld",ANS.a[i][j]);
printf(j==n ? "\n" : " ");
}
}
#undef int
int main()
{
//freopen("P3390_1.in","r",stdin);freopen("P3390.out","w",stdout);
work();
return 0;
}
posted @   liuboom  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示