UVA 11149 Power of Matrix 快速幂
2016-07-17 21:15
387 查看
题目链接:
http://acm.hust.edu.cn/vjudge/contest/122094#problem/GPower of Matrix
Time Limit:3000MSMemory 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+A^2+...A^k=(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; }
相关文章推荐
- select中option改变时跳转到其他页面
- Remove Invalid Parentheses -- Leetcode
- 如何在window本地按章nodejs
- HDU 2822 Dogs(优先队列)
- 机器学习基础 维基翻译 Johnson-Lindenstrauss降维 应用于广义因子模型 及简单的sklearn例子
- 关于vim的用法
- PAT甲级练习题A1003. Emergency
- Hibernate查询,常用的指定返回类型方式
- MVN相关命令集
- codeforces 234E Champions' League
- Java工具类之Date日期操作工具类
- 错误号org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe
- 转行|如何成为企业想要的Android工程师
- POJ 2752 KMP中next数组的应用
- Java软件工程师的基础知识点
- POJ 2752 KMP中next数组的应用
- android studio 怎么将项目打包成apk文件
- 开发前端框架_1
- 蓝牙聊天
- 用virtualbox安装CentOS 7