在我们求一些递推式子是,如果一味的使用for可能在数据很大的时候就超时,所以引入矩阵快速幂
将递推关系隐藏在初始矩阵中,然后使用矩阵快速幂降低时间,就可求出
https://www.luogu.org/problem/P3390
/*
Name:
Copyright:
Author: 流照君
Date: 2019/8/12 15:05:21
Description:
*/
#include <iostream>
#include<string>
#include <algorithm>
#include <vector>
#include<cstring>
#define inf 100
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll n;
struct matrix{
ll a[inf][inf];//构造函数
matrix(){
memset(a,0,sizeof(a));
}
inline void bulid()//初始化
{
for(int i=1;i<=n;i++)
a[i][i]=1;
}
};
matrix ma,unit;
matrix operator*(const matrix &x,const matrix &y)//重载运算符
{
matrix ans;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod;
}
return ans;
}
matrix pow(matrix ma1,ll k)
{
matrix ans;
ans.bulid();
do
{
if(k&1)
ans=ans*ma1;
ma1=ma1*ma1;
k=k/2;
}while(k);
return ans;
}
int main(int argc, char** argv)
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
ll k;
scanf("%lld %lld",&n,&k);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%lld",&ma.a[i][j]);
}
}
unit.bulid();
matrix res=pow(ma,k);
for(int i=1;i<=n;cout<<endl,++i)
for(int j=1;j<=n;++j)
printf("%lld ",res.a[i][j]);
return 0;
}
其中乘法可以不重载,而使用函数
转载一段话————————————————————————————————————————————————————————————————————
那么,矩阵乘法的优越性究竟体现在哪里呢。其实,矩阵乘法只是体现了我们从之前求的数到现在要求的数的递推过程,就是说矩阵乘法可以完成多个元素的递推。不过这个我们用普通的递推就可以实现的啊~~认真想想我们就能发现,我们在矩阵乘法的过程中把上见面的A矩阵自己相乘了很多遍。就是说,我们可以求A矩阵的幂最后乘上B矩阵,既然要求幂,矩阵乘法满足结合律,那么我们就可以用快速幂啦~~矩阵乘法的优越性就体现在这里:在递推过程变成不断乘以一个矩阵,然后用快速幂快速求得从第一个到第n个的递推式,这样子就可以在短时间内完成递推了。
哇塞,人类的智商啊~~让我们继续膜拜那些智商正无穷的大神吧,orz,orz…… 链接https://www.cnblogs.com/Konjakmoyu/p/4821044.html