题目
算法分析
这是一道板子题,开始之前我们来简单学习一下矩阵乘法:
相信你对矩阵乘法已经有了初步的理解,如果看完上面那篇文仍然不太明白,下面这篇一定会让你豁然开朗;
本题中的矩阵快速幂,在你理解过矩阵乘法后就很简单,一句话而已:
本人代码如下:
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
#define rg register
using namespace std;
inline int sread()
{
int x=0,f=1;char c=getchar();
while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return f*x;
}
const int p=1000000000+7;
int n;
ll k;
struct node{
ll mp[105][105];
};
node mul(node a,node b)
{
node c;
for(rg int i=1;i<=n;++i)
{
for(rg int j=1;j<=n;++j)
{
c.mp[i][j]=0;
for(rg ll k=1;k<=n;++k)
{
c.mp[i][j]+=((a.mp[i][k]%p)*(b.mp[k][j]%p))%p;
}
}
}
return c;
}
node quickpow(node mp,ll b)
{
node ans,base=mp;
for(rg int i=1;i<=n;++i) ans.mp[i][i]=1;
while(b)
{
if(b&1) ans=mul(ans,base);
base=mul(base,base);
b>>=1;
}
return ans;
}
int main()
{
n=sread(); scanf("%lld",&k);
node G,_ans;
for(rg int i=1;i<=n;++i)
{
for(rg int j=1;j<=n;++j)
{
scanf("%lld",&G.mp[i][j]);
G.mp[i][j]=G.mp[i][j]%p;
}
}
_ans=quickpow(G,k);
for(rg int i=1;i<=n;++i)
{
for(rg int j=1;j<=n;++j)
{
printf("%lld ",_ans.mp[i][j]%p);
}
printf("\n");
}
return 0;
}
反思与总结
本题是一道板子题,只要充分理解并能熟练运用就好啦。还要在具体试题中去发现并且运用呀!
经典例题:
Luogu:P1962 斐波那契数列
Luogu:P1349 广义斐波那契数列
经典例题 算法分析:
数论——矩阵乘法 + P1962 斐波那契数列 + P1349 广义斐波那契数列