poj 3233 矩阵乘法(分块矩阵)

POJ 3233



题解:Sn为所求矩阵, 则


这样, 此题就变成了求矩阵幂和矩阵乘法, 分块矩阵乘法和普通矩阵一样的。



code:

/*
adrui's submission
Language : C++
Result : Accepted
Love : ll
Favorite : Dragon Balls

Standing in the Hall of Fame
*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#include<bitset>
#include<map>
using namespace std;

#define M(a, b) memset(a, b, sizeof(a))
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1|1, mid + 1, r
#define lowbit(x) (x & (-x))
#define LL long long
#define REP(n) for(int i = 0; i < n; i++)
#define debug 0
#define mod 1000

int n, k, m;

struct Matrix {
	int mat[65][65];														//分块矩阵原因, size要是2倍
	void init() {															//单位矩阵
		M(mat, 0);
		for (int i = 0; i < 65; i++)
			mat[i][i] = 1;
	}
	void output(int c) {
		for (int i = 0; i < c; i++) {
			for (int j = 0; j < c; j++)
			{
				printf("%d%s", mat[i][j] % m, j != c - 1 ? " " : "\n"); 
			}
		}
	}
};

Matrix operator * (Matrix a, Matrix b) {									//矩阵乘法
	Matrix c;	
	M(c.mat, 0);
		for (int i = 0; i < 2 * n; i++) {
			for (int j = 0; j < 2 * n; j++)
			{
				for (int k = 0; k < 2 * n; k++)
					c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % m;
				c.mat[i][j] %= m;
			}
		}

	return c;
}

Matrix operator + (const Matrix &a, const Matrix &b) {						//矩阵加法
	Matrix c;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++)
			{
				c.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % m;
			}
		}
		//c.output();
	return c;
}

Matrix Matrix_fast_mod(Matrix tmp, int b) {									//快速矩阵幂
	Matrix res;
	res.init();																//单位矩阵
	while (b) {
		if (b & 1) res = tmp * res;
		tmp = tmp * tmp;
		b >>= 1;
	}
	return res;
}

int main() {
#if debug
	freopen("in.txt", "r", stdin);
#endif //debug
	
	while (~scanf("%d%d%d", &n, &k, &m)) {
		Matrix ans, b;
		M(b.mat, 0);
		Matrix res;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				scanf("%d", &res.mat[i][j]);
				res.mat[i][j] %= m;
				b.mat[i][j] = res.mat[i][j];								//b是幂底数矩阵
				res.mat[i][n + j] = res.mat[i][j];							//ret是包含Sn的分块矩阵
			}
			b.mat[n + i][i] = b.mat[n + i][n + i] = 1;
		}
		//b.output(2 * n);
		b = Matrix_fast_mod(b, k - 1);										//矩阵幂
		//b.output(2*n);
		//res.output(2 * n);
		ans = res * b;


		ans.output(n);										//输出
	}
	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值