【矩阵乘法】矩阵求和

链接

YbtOJ 6-1-4

题目描述

给出一个nn的矩阵和一个正整数k ,求S = A * A^2 * A ^ 3… A^k 。矩阵中的每个数对 取模。

思路

构建一个矩阵B,左上放一个矩阵A,右上放一个大小相同的单位矩阵,右下也放一个同样大小的单位矩阵,然后直接跑快速幂就好了

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long

using namespace std;

ll n, m, tk;

struct matrix
{
	ll n, m;
	ll a[105][105];
}A, B, Ans;

void pre()
{
	for(int i = 1; i <= 2 * n; ++i)
		Ans.a[i][i] = 1;
	B.n = B.m = Ans.n = Ans.m = n * 2;
}

matrix operator *(matrix a, matrix b)
{
	matrix c;
	c.n = a.n;
	c.m = b.m;
	memset(c.a, 0, sizeof(c.a));
	for(int k = 1; k <= a.m; ++k)
	for(int i = 1; i <= c.n; ++i)
	for(int j = 1; j <= c.m; ++j)
		c.a[i][j] = (c.a[i][j] + (a.a[i][k] * b.a[k][j]) % m) % m;
	return c;
}

void quick_pow(ll t)
{
	while(t)
	{
		if(t & 1) Ans = Ans * B;
		B = B * B;
		t >>= 1;
	}
}

int main()
{
	scanf("%lld%lld%lld", &n, &tk, &m);
	pre();
	for(int i = 1; i <= n; ++i)
	for(int j = 1; j <= n; ++j)
		scanf("%lld", &A.a[i][j]);
		
	for(int i = 1; i <= n; ++i)
	for(int j = 1; j <= n; ++j)
		B.a[i][j] = A.a[i][j];
	for(int i = 1; i <= n; ++i)
	for(int j = n + 1; j <= 2 * n; ++j)
		if(i == j - n) B.a[i][j] = 1;
	for(int i = n + 1; i <= 2 * n; ++i)
	for(int j = 1; j <= n; ++j)
		B.a[i][j] = 0;
	for(int i = n + 1; i <= 2 * n; ++i)
	for(int j = n + 1; j <= 2 * n; ++j)
		if(i == j) B.a[i][j] = 1;
		
	quick_pow(tk + 1);
	for(int i = 1; i <= n; ++i) {
		for(int j = n + 1; j <= 2 * n; ++j)
			if(i == j - n) printf("%lld ", (Ans.a[i][j] - 1) % m);//要把原来的单位矩阵删掉
				else printf("%lld ", Ans.a[i][j] % m);
		printf("\n");
	}
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值