HDOJ-----1575---Tr A矩阵快速幂

A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973。
 

Input
数据的第一行是一个T,表示有T组数据。
每组数据的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)两个数据。接下来有n行,每行有n个数据,每个数据的范围是[0,9],表示方阵A的内容。
 

Output
对应每组数据,输出Tr(A^k)%9973。
 

Sample Input
  
  
2 2 2 1 0 0 1 3 99999999 1 2 3 4 5 6 7 8 9
 

Sample Output
  
  
2 2686

矩阵运算,数学不好是硬伤---

思想还是快速幂,只不过把数字换成了矩阵,再然后就是矩阵运算了

两矩阵A,B相乘得到新矩阵C,C[i][j]等于所有A矩阵第i行第k列数字与矩阵B第k行第j列数字的乘积之和

最后求的矩阵的快速幂,再计算新矩阵的迹,即主对角线之和

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<functional>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define CL(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long LL;
const int maxn = 5e4+10;
const int MOD = 1e9+7; 
struct matrix{
	int pos[20][20];
};
matrix  A, B;
int n, k;
matrix mul_matrix(matrix A, matrix B){
	matrix C;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < n; j++){
			C.pos[i][j] = 0;
			for(int k = 0; k < n; k++){
				C.pos[i][j] = (C.pos[i][j] + A.pos[i][k]*B.pos[k][j]%9973) % 9973;
			}
			C.pos[i][j] %= 9973;
		}
	}
	return C;
}
matrix quick_pow(matrix A, matrix B, int b){//把数字改为矩阵的快速幂
	while(b){
		if(b&1){
			B = mul_matrix(B, A);
		}
		b >>= 1;
		A = mul_matrix(A, A);
	}
	return B;
}
int main(){  
    int t, kcase = 1;
    scanf("%d", &t);
    while(t--){
    	scanf("%d%d", &n, &k);
    	for(int i = 0; i < n; i++){
    		for(int j = 0; j < n; j++){
    			scanf("%d", &A.pos[i][j]);
    			B.pos[i][j] = A.pos[i][j];
			}
		}
		int ans = 0;
		B = quick_pow(A, B, k-1);//B此时和A相等,要求A^k,即A^(k-1)*B,即A^(k-1)*A
		for(int i = 0; i < n; i++) ans = (ans + B.pos[i][i]) % 9973;//主对角线之和
		printf("%d\n", ans % 9973);
	}
    return 0;  
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值