题目链接:

http://acm.hust.edu.cn/vjudge/contest/122094#problem/G

Power of Matrix

Time Limit:3000MS
Memory Limit:0KB
#### 问题描述
> 给你一个矩阵A,求A+A^2+A^3+...+A^k
#### 输入
> Input consists of no more than 20 test cases. The first line for each case contains two positive integers n
> (≤ 40) and k (≤ 1000000). This is followed by n lines, each containing n non-negative integers, giving
> the matrix A.
> Input is terminated by a case where n = 0. This case need NOT be processed.

输出

For each case, your program should compute the matrix A + A2 + A3 + . . . + Ak

. Since the values may

be very large, you only need to print their last digit. Print a blank line after each case.

样例

sample input

3 2

0 2 0

0 0 2

0 0 0

0 0

sample output

0 2 4

0 0 2

0 0 0

题解

A+A2+...Ak=(I+A(n/2))(A+...+A(n/2))=...

一直递推下去,深度只有logn,只要logn次快速幂求A^x。

代码

WA四次的代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; const int maxn = 55;
const int mod = 10;
typedef int LL; struct Matrix {
LL mat[maxn][maxn];
Matrix() { memset(mat, 0, sizeof(mat)); }
friend Matrix operator *(const Matrix& A, const Matrix& B);
friend Matrix operator +(const Matrix &A,const Matrix &B);
friend Matrix operator ^(Matrix A, int n);
}; Matrix I; Matrix operator +(const Matrix& A, const Matrix& B) {
Matrix ret;
for (int i = 0; i < maxn; i++) {
for (int j = 0; j < maxn; j++) {
ret.mat[i][j] = (A.mat[i][j] + B.mat[i][j])%mod;
}
}
return ret;
} Matrix operator *(const Matrix& A, const Matrix& B) {
Matrix ret;
for (int i = 0; i < maxn; i++) {
for (int j = 0; j < maxn; j++) {
for (int k = 0; k < maxn; k++) {
ret.mat[i][j] = (ret.mat[i][j]+A.mat[i][k] * B.mat[k][j]) % mod;
}
}
}
return ret;
} Matrix operator ^(Matrix A, int n) {
Matrix ret=I;
while (n) {
if (n & 1) ret = ret*A;
A = A*A;
n /= 2;
}
return ret;
} Matrix solve(Matrix A, int n) {
if (!n) return I;
if (n == 1) return A;
//这里要加括号!!! ret=I+(A^(n/2))!!!
Matrix ret = I + A ^ (n / 2);
ret = ret*solve(A, n / 2);
//这里也要加!!!! ret=ret+(A^n)!!!
if (n % 2) ret = ret + A^n;
return ret;
} int n, k; int main() {
for (int i = 0; i < maxn; i++) I.mat[i][i] = 1;
while (scanf("%d%d", &n, &k) == 2 && n) {
Matrix A;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &A.mat[i][j]);
A.mat[i][j] %= mod;
}
}
Matrix ans=solve(A, k);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n-1; j++) {
printf("%d ",ans.mat[i][j]);
}
printf("%d\n", ans.mat[i][n - 1]);
}
printf("\n");
}
return 0;
}

保险一些的写法:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std; const int maxn = 55;
const int mod = 10;
typedef int LL; struct Matrix {
LL mat[maxn][maxn];
Matrix() { memset(mat, 0, sizeof(mat)); }
friend Matrix operator *(const Matrix& A, const Matrix& B);
friend Matrix operator +(const Matrix &A,const Matrix &B);
friend Matrix pow(Matrix A, int n);
}; Matrix I; Matrix operator +(const Matrix& A, const Matrix& B) {
Matrix ret;
for (int i = 0; i < maxn; i++) {
for (int j = 0; j < maxn; j++) {
ret.mat[i][j] = (A.mat[i][j] + B.mat[i][j])%mod;
}
}
return ret;
} Matrix operator *(const Matrix& A, const Matrix& B) {
Matrix ret;
for (int i = 0; i < maxn; i++) {
for (int j = 0; j < maxn; j++) {
for (int k = 0; k < maxn; k++) {
ret.mat[i][j] = (ret.mat[i][j]+A.mat[i][k] * B.mat[k][j]) % mod;
}
}
}
return ret;
} Matrix pow(Matrix A, int n) {
Matrix ret=I;
while (n) {
if (n & 1) ret = ret*A;
A = A*A;
n /= 2;
}
return ret;
} Matrix solve(Matrix A, int n) {
if (!n) return I;
if (n == 1) return A;
Matrix ret = I + pow(A,n/2);
ret = ret*solve(A, n / 2);
if (n % 2) ret = ret + pow(A,n);
return ret;
} int n, k; int main() {
for (int i = 0; i < maxn; i++) I.mat[i][i] = 1;
while (scanf("%d%d", &n, &k) == 2 && n) {
Matrix A;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &A.mat[i][j]);
A.mat[i][j] %= mod;
}
}
Matrix ans=solve(A, k);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n-1; j++) {
printf("%d ",ans.mat[i][j]);
}
printf("%d\n", ans.mat[i][n - 1]);
}
printf("\n");
}
return 0;
}

UVA 11149 Power of Matrix 快速幂的更多相关文章

  1. UVA 11149 - Power of Matrix(矩阵乘法)

    UVA 11149 - Power of Matrix 题目链接 题意:给定一个n*n的矩阵A和k,求∑kiAi 思路:利用倍增去搞.∑kiAi=(1+Ak/2)∑k/2iAi,不断二分就可以 代码: ...

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

    题意:求A + A^2 + A^3 + ... + A^m. 析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))( ...

  3. UVa 11149 Power of Matrix(倍增法、矩阵快速幂)

    题目链接: 传送门 Power of Matrix Time Limit: 3000MS      Description 给一个n阶方阵,求A1+A2+A3+......Ak. 思路 A1+A2+. ...

  4. UVA 11149 Power of Matrix

    矩阵快速幂. 读入A矩阵之后,马上对A矩阵每一个元素%10,否则会WA..... #include<cstdio> #include<cstring> #include< ...

  5. UVa 11149 Power of Matrix 矩阵快速幂

    题意: 给出一个\(n \times n\)的矩阵\(A\),求\(A+A^2+A^3+ \cdots + A^k\). 分析: 这题是有\(k=0\)的情况,我们一开始先特判一下,直接输出单位矩阵\ ...

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

    题意:已知N*N的矩阵A,输出矩阵A + A2 + A3 + . . . + Ak,每个元素只输出最后一个数字. 分析: A + A2 + A3 + . . . + An可整理为下式, 从而可以用lo ...

  7. UVA 11149 Power of Matrix 构造矩阵

    题目大意:意思就是让求A(A是矩阵)+A2+A3+A4+A5+A6+······+AK,其中矩阵范围n<=40,k<=1000000. 解题思路:由于k的取值范围很大,所以很自然地想到了二 ...

  8. UVA 11149.Power of Matrix-矩阵快速幂倍增

    Power of Matrix UVA - 11149       代码: #include <cstdio> #include <cstring> #include < ...

  9. POJ 3233:Matrix Power Series 矩阵快速幂 乘积

    Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 18450   Accepted:  ...

随机推荐

  1. MySQL之学生名次问题

    --对输入的数据进行约束create table t(studentID char(10), [name] varchar(8), startDate char(10) Check (isdate(s ...

  2. UI1_UIScrollView

    // // AppDelegate.m // UI1_UIScrollView // // Created by zhangxueming on 15/7/10. // Copyright (c) 2 ...

  3. php折线图 布局图

    例子1: 1 <?php require_once("../conf.php"); ?> <!DOCTYPE HTML> <html> < ...

  4. (转)Couchbase介绍,更好的Cache系统

    在移动互联网时代,我们面对的是更多的客户端,更低的请求延迟,这当然需要对数据做大量的 Cache 以提高读写速度. 术语 节点:指集群里的一台服务器. 现有 Cache 系统的特点 目前业界使用得最多 ...

  5. android ListView的介绍和优化

    xml设计 <?xml version="1.0"?> -<RelativeLayout tools:context=".MainActivity&qu ...

  6. Java线程面试题 Top 50(转载)

    原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎加入Java小组.转载请参见文章末尾的 ...

  7. C++ 11 之学习总结

    感慨时间过的好快,C++ 11出来都5年了,现在才开始学习,但为时也不晚: 主要是网上及身边的朋友大肆宣扬C++ 11的某些优化,弄得别人心里痒痒的,所以就花了3天学习了点基本知识,相对于整个C++ ...

  8. 编译安装HTTPD 2.4.9版本

    编译安装HTTPD 2.4.9版本    服务脚本:/etc/rc.d/init.d/httpd    脚本配置文件路径:/etc/sysconfig/httpd    运行目录:/etc/httpd ...

  9. Java操作MongoDB

    上一篇文章: http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html 介绍到了在MongoDB的控制台完成MongoDB的数据操作,通 ...

  10. 数据的增量更新之EXISTS

    有时候需要实现是数据的增量更新,因为更新全量会带来时间跟数据库资源的浪费,还有可能是数据出现冗余,所以需要使用增量数据同步,下面是一个数据增量同步的小实例. ---drop table A CREAT ...