矩阵快速幂 学习笔记

最近学习新知的速度是真的越来越快了,所以没有办法像以前那样慢慢写,就只好整合一下了。
由于时间关系,标准定义类的那些可以百度到的东西不多赘述,这里只谈自己的理解。


首先,我们需要了解矩阵。矩阵说白了就是一堆数,排成长方形的形状。
然后就是矩阵的运算,加减都很简单,这里谈一下乘法:
矩阵快速幂 学习笔记_第1张图片

所以矩阵相乘,一定是有其中一个矩阵的行等于另一个矩阵的列的。

矩阵快速幂则和一般的快速幂的操作是一样的,只是把乘法变成了矩阵乘而已,就像重载那样。
这里还要说一下单位矩阵:
对于 n ∗ m n*m nm的矩阵,它的单位矩阵大小为 m ∗ m m*m mm,对于 m ∗ n m*n mn的矩阵,它的单位矩阵大小为 n ∗ n n*n nn
也就是说单位矩阵都是正方形的,这是因为只有正方形的矩阵能保证结果和前一个矩阵形状相同。
单位矩阵的元素非0即1,从左上角到右下角的对角线上元素皆为1,其他皆为0。
单位矩阵的意义就是它相当于普通乘法里面的1,和任何数乘1都等于它本身那样,任何矩阵乘单位矩阵都等于原矩阵。

模板:
洛谷P3390

#include
#include
using namespace std;
#define N 105
#define ll long long
#define MOD 1000000007
int n;
ll k;
struct node{
	ll m[N][N];
};
node a,E/*单位矩阵*/;
node Mul(node x,node y)
{
	node z;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			z.m[i][j]=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			for(int k=1;k<=n;k++)
				z.m[i][j]=(z.m[i][j]%MOD+x.m[i][k]*y.m[k][j]%MOD)%MOD;
	return z;
}
node Pow(node x,ll y)
{
	node ans=E;
	while(y)
	{
		if(y&1)
			ans=Mul(ans,x);
		x=Mul(x,x);
		y>>=1;
	}
	return ans;
}
int main()
{
	scanf("%d %lld",&n,&k);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			scanf("%lld",&a.m[i][j]);
		E.m[i][i]=1;
	}
	node ans=Pow(a,k);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<n;j++)
			printf("%d ",ans.m[i][j]);
		printf("%d\n",ans.m[i][n]);
	}
}

你可能感兴趣的:(矩阵快速幂)