矩阵快速幂【矩阵乘法】【模板】

>Link

luogu P3390


>Description

给定 N ∗ N N*N NN的矩阵 A A A,求 A k A^k Ak


>解题思路

矩阵乘法模板题

矩阵乘法:
定义 n ∗ q n*q nq 矩阵 A A A q ∗ m q*m qm 矩阵 B B B A ∗ B = C A*B=C AB=C,得到 n ∗ m n*m nm 的矩阵 C C C
其中, c i , j = Σ k = 1 q a i , k ∗ b k , j c_{i,j}=Σ_{k=1}^{q}a_{i,k}*b_{k,j} ci,j=Σk=1qai,kbk,j

由此看出,矩阵乘法支持结合律,不支持交换律

矩阵乘法快速幂直接 普通快速幂+矩阵乘法


>代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define LL long long
using namespace std;

const LL p = 1e9 + 7;
struct matrix
{
	int x, y;
	LL a[110][110];
};
int n;
LL k;

matrix operator *(matrix a, matrix b) //重新定义乘法(矩阵)
{
	matrix c;
	c.x = a.x, c.y = b.y;
	for (int i = 1; i <= c.x; i++)
	  for (int j = 1; j <= c.y; j++)
	    c.a[i][j] = 0;
	for (int k = 1; k <= a.y; k++)
	  for (int i = 1; i <= a.x; i++)
	    for (int j = 1; j <= b.y; j++)
	      c.a[i][j] = (c.a[i][j] + a.a[i][k] * b.a[k][j] % p) % p;
	return c;
}
matrix power (matrix A, LL k)
{
	bool mark = 0;
	matrix ret;
	ret.x = ret.y = A.x;
	for (; k; k >>= 1, A = A * A)
	  if (k & 1)
	  {
	  	if (!mark)
	  	{
			for (int i = 1; i <= ret.x; i++)
	  		  for (int j = 1; j <= ret.y; j++)
	    		ret.a[i][j] = A.a[i][j] % p;
	    	mark = 1;
		}
	  	else ret = ret * A;
	  }
	return ret;
}

int main()
{
	scanf ("%d%lld", &n, &k);
	matrix A, ans;
	A.x = A.y = n;
	for (int i = 1; i <= n; i++)
	  for (int j = 1; j <= n; j++)
	    scanf ("%lld", &A.a[i][j]);
	ans = power (A, k);
	for (int i = 1; i <= ans.x; i++)
	{
		for (int j = 1; j <= ans.y; j++)
		  printf ("%lld ", ans.a[i][j]);
		printf ("\n");
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值