其他分享
首页 > 其他分享> > 【矩阵乘法】矩阵求和

【矩阵乘法】矩阵求和

作者:互联网

小目录

链接

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;
} 

标签:求和,单位矩阵,ll,矩阵,int,Ans,include,乘法
来源: https://blog.csdn.net/LTH060226/article/details/121579009