UVa 11149 - Power of Matrix

题目:一直方阵A,计算A + A^2 + A^3 + ... + A^n。

分析:分治,快速模幂。

设F(n)= A + A^2 + A^3 + ... + A^n则有;

F(n)= F(n/2)+ F(n/2)* A^(n/2)+ R;(n为奇数存在R,为A^n)

= F(n/2){E + A^(n/2)} + R;

利用递归和分治求解即可。

说明:读入的数据直接取模,否则会溢出╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

class matrix
{
	private:
		int data[41][41];
	public:
		matrix(){}
		matrix(int n) {
			for (int i = 0; i < n; ++ i)
			for (int j = 0; j < n; ++ j) {
				scanf("%d",&data[i][j]);
				data[i][j] %= 10;
			}
		}
		void show(int n) {
			for (int i = 0; i < n; ++ i)
			for (int j = 0; j < n; ++ j) {
				printf("%d",data[i][j]);
				if (j == n-1) printf("\n");
				else printf(" ");
			}printf("\n");
		}
		friend matrix E(matrix mat, int n);
		friend matrix add(matrix A, matrix B, int n);
		friend matrix mul(matrix A, matrix B, int n);
		friend matrix qpow(matrix mat, int k);
		friend matrix spow(matrix mat, int k);
};
//单位矩阵
matrix E(matrix mat, int n)
{
	for (int i = 0; i < n; ++ i)
	for (int j = 0; j < n; ++ j)
		mat.data[i][j] = (i==j);
	return mat;
}
//矩阵加法
matrix add(matrix A, matrix B, int n)
{
	matrix C;
	for (int i = 0 ; i < n; ++ i)
		for (int j = 0 ; j < n; ++ j)
			C.data[i][j] = (A.data[i][j]+B.data[i][j])%10;
	return C;
}
//矩阵乘法
matrix mul(matrix A, matrix B, int n)
{
	matrix C;
	for (int i = 0 ; i < n ; ++ i)
		for (int j = 0 ; j < n ; ++ j) {
			C.data[i][j] = 0;
			for (int k = 0 ; k < n ; ++ k)
				C.data[i][j] = (C.data[i][j]+A.data[i][k]*B.data[k][j])%10;
	}
	return C;
}
//矩阵快速幂
matrix qpow(matrix mat, int k, int n)
{
	if (k == 1) return mat;
	matrix now = qpow(mat, k/2, n);
	if (k%2 == 0) return mul(now, now, n);
	return mul(mul(now, now, n), mat, n);
}
//矩阵快速幂和
matrix spow(matrix mat, int k, int n)
{
	if (k == 1) return mat;
	matrix A = spow(mat, k/2, n);
	matrix B = add(qpow(mat, k/2, n), E(mat, n), n);
	if (k%2 == 0) return mul(A, B, n);
	else return add(mul(A, B, n), qpow(mat, k, n), n);
}

int main()
{
	int n,k;
	while (cin >> n >> k && n)
		spow(matrix(n), k, n).show(n);
    return 0;
}
时间: 2025-01-14 00:45:57

UVa 11149 - Power of Matrix的相关文章

UVA 11149 - Power of Matrix(矩阵倍增)

UVA 11149 - Power of Matrix 题目链接 题意:给定一个n*n的矩阵A和k,求∑kiAi 思路:利用倍增去搞,∑kiAi=(1+Ak/2)∑k/2iAi,不断二分即可 代码: #include <cstdio> #include <cstring> const int N = 45; int n, k; struct mat { int v[N][N]; mat() {memset(v, 0, sizeof(v));} mat operator * (mat

Uva 11149 - Power of Matrix ( 矩阵快速幂 )

Uva 11149 -Power of Matrix ( 矩阵快速幂 ) #include <cstdio> #include <cstring> #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 10 #define MAX_SIZE 40 struct Mat { int r, c; int mat[MAX_SIZE][MAX_SIZE]; Mat( int _r = 0 , int _c = 0 ) { CLR

UVA - 11149 Power of Matrix(矩阵倍增)

题意:已知N*N的矩阵A,输出矩阵A + A2 + A3 + . . . + Ak,每个元素只输出最后一个数字. 分析: A + A2 + A3 + . . . + An可整理为下式, 从而可以用log2(n)的复杂度算出结果. 注意:输入时把矩阵A的每个元素对10取余,因为若不处理,会导致k为1的时候结果出错. #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #in

UVa 11149 Power of Matrix (矩阵快速幂,倍增法或构造矩阵)

题意:求A + A^2 + A^3 + ... + A^m. 析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))(A + A^2 + A^3 + ... + A^(m/2)),然后依次计算下去,就可以分解,logn的复杂度分解,注意要分奇偶. 另一种是直接构造矩阵,,然后就可以用辞阵快速幂计算了,注意要用分块矩阵的乘法. 代码如下: 倍增法: #pragma comment(linker, "/STACK:10

UVA 11149 Power of Matrix 构造矩阵

题目大意:意思就是让求A(A是矩阵)+A2+A3+A4+A5+A6+······+AK,其中矩阵范围n<=40,k<=1000000. 解题思路:由于k的取值范围很大,所以很自然地想到了二分法,用递归逐步将k二分(公式:A+A2+A3+A4+A5+A6 = A+A2+A3 + A3(A+A2+A3)), 这种方法只需要注意k是奇数的情况就可以了. 最坑的是第二种方法,根据矩阵的性质可以构造出来一个子矩阵,假如有矩阵B=|A  E| ,那么BK =|AK   E+ A+A2+A3+A4+A5+A

Power of Matrix(uva11149+矩阵快速幂)

Power of Matrix Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 11149 Appoint description:  System Crawler  (2015-03-15) Description Problem B : Power of Matrix Time limit: 10 seconds Consider an n-by

UVa 10298 - Power Strings

题目:求一个串的最大的循环次数. 分析:dp,KMP,字符串.这里利用KMP算法. KMP的next函数是跳跃到最近的串的递归结构位置(串元素取值0 ~ len-1): 由KMP过程可知: 如果存在循环节,则S[0 ~ next[len]-1] 与 S[len-next[len] ~ len-1]相匹配: 则S[next[len] ~ len-1]就是循环节(且最小),否则next[len]为0: 因此,最大循环次数为len/(len-next[len]),最小循环节为S[next[len] ~

UVA - 10298 Power Strings (KMP求字符串循环节)

Description Problem D: Power Strings Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiati

[2016-03-03][UVA][1374][Power Calculus]

[2016-03-03][UVA][1374][Power Calculus] 时间:2016-03-03 16:14:01 星期四 题目编号:UVA 1374 题目大意:给出x的指数n,问,x经过多少次相乘才能得到x^n 输入:n 输出:次数 分析: 求乘法的所有可能方式,用dfs,适当剪枝优化,变成IDA* x的乘法,变成了指数的加法 每次不断平方,最少次数 为 不断平方的次数.这个为maxd起点 方法: 枚举每一位出现过的次数,当前字数加上枚举出来的次数,进入下一层dfs 剪枝:如果预计最