【矩阵幂的和+矩阵快速幂】Power of Matrix UVA - 11149

本是古典 何须时尚 2022-06-07 06:09 278阅读 0赞

Think:
1知识点:矩阵幂的和+矩阵快速幂
2题意:输入矩阵A,求A^1 + A^2 + … + A^(n)
3题意分析:
(1):倍增法求矩阵幂的和,eg:
求:A^1 + A^2 + A^3 + A^4 + A^5 + A^6 + A^7 + A^8 + A^9 + A^10
(1):A^1 + A^2 + A^3 + A^4 + A^5 + A^6 + A^7 + A^8 + A^9 + A^10 = (A^1+A^2+A^3+A^4+A^5) + (A^5)*(A^1+A^2+A^3+A^4+A^5)
(2):A^1 + A^2 + A^3 + A^4 + A^5 = (A^1+A^2) + (A^2)*(A^1+A^2) + A^5
(3):A^1 + A^2 = (A^1) + (A^1)*(A^1)
(4):A^1 = A^1
代码实现如下:

  1. /*倍增法求解A^1 + A^2 + ... + A^n*/
  2. Matrix pow_sum(const Matrix &a, int n){
  3. ///递归终点
  4. if(n == 1) return a;
  5. ///tmp递归表示A^1 + A^2 + ... + A^(n/2)
  6. Matrix tmp = pow_sum(a, n/2);
  7. ///sum表示(A^1+...+A^(n/2)) + (A^1+...+A^(n/2))*(A^(n/2))
  8. Matrix sum = tmp + tmp*a.pow(n/2);
  9. ///若n为奇数,n/2 + n/2 = n-1, 因此sum需要加上A^(n)这一项
  10. if(n & 1) sum = sum + a.pow(n);
  11. return sum;
  12. }

4反思:
(1):构造函数只声明未定义——error:ld returned 1 exit status
(2):删除构造函数2之后,有的函数未补充().v数组初始化

vjudge题目链接
建议参考博客——分析+代码实现

以下为Accepted代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int mod = 10;
  6. class Matrix{
  7. public:
  8. int row, col;
  9. int v[54][54];
  10. Matrix(){}
  11. ~Matrix(){}
  12. Matrix operator + (const Matrix &sec) const;
  13. Matrix operator * (const Matrix &sec) const;
  14. Matrix & operator = (const Matrix &sec);
  15. Matrix pow(int n) const;
  16. };
  17. Matrix Matrix::operator + (const Matrix &sec) const{
  18. Matrix tmp;
  19. tmp.row = sec.row, tmp.col = sec.col;
  20. for(int i = 1; i <= tmp.row; i++){
  21. for(int j = 1; j <= tmp.col; j++){
  22. tmp.v[i][j] = (v[i][j] + sec.v[i][j]) % mod;
  23. }
  24. }
  25. return tmp;
  26. }
  27. Matrix Matrix::operator * (const Matrix &sec) const{
  28. Matrix tmp;
  29. tmp.row = row, tmp.col = sec.col;
  30. memset(tmp.v, 0, sizeof(tmp.v));
  31. for(int i = 1; i <= row; i++){
  32. for(int j = 1; j <= sec.col; j++){
  33. for(int k = 1; k <= col; k++){
  34. tmp.v[i][j] += (v[i][k]*sec.v[k][j]);
  35. tmp.v[i][j] %= mod;
  36. }
  37. }
  38. }
  39. return tmp;
  40. }
  41. Matrix & Matrix::operator = (const Matrix &sec){
  42. for(int i = 1; i <= row; i++){
  43. for(int j = 1; j <= col; j++){
  44. v[i][j] = sec.v[i][j];
  45. }
  46. }
  47. return *this;
  48. }
  49. Matrix Matrix::pow(int n) const{
  50. Matrix a(*this);
  51. Matrix ans;
  52. ans.row = row, ans.col = col;
  53. memset(ans.v, 0, sizeof(ans.v));
  54. for(int i = 1; i <= ans.row; i++)
  55. ans.v[i][i] = 1;
  56. while(n){
  57. if(n & 1)
  58. ans = ans * a;
  59. a = a * a;
  60. n >>= 1;
  61. }
  62. return ans;
  63. }
  64. Matrix pow_sum(const Matrix &a, int n);/*倍增法求解A^1 + A^2 + ... + A^n*/
  65. int main(){
  66. int n, r, i, j;
  67. while(~scanf("%d %d", &n, &r) && n){
  68. Matrix test;
  69. test.row = n, test.col = n;
  70. for(i = 1; i <= test.row; i++){
  71. for(j = 1; j <= test.col; j++){
  72. scanf("%d", &test.v[i][j]);
  73. test.v[i][j] %= 10;
  74. }
  75. }
  76. Matrix ans = pow_sum(test, r);
  77. for(i = 1; i <= ans.row; i++){
  78. for(j = 1; j <= ans.col; j++){
  79. printf("%d%c", ans.v[i][j], j == ans.col? '\n': ' ');
  80. }
  81. }
  82. printf("\n");
  83. }
  84. return 0;
  85. }
  86. /*倍增法求解A^1 + A^2 + ... + A^n*/
  87. Matrix pow_sum(const Matrix &a, int n){
  88. ///递归终点
  89. if(n == 1) return a;
  90. ///tmp递归表示A^1 + A^2 + ... + A^(n/2)
  91. Matrix tmp = pow_sum(a, n/2);
  92. ///sum表示(A^1+...+A^(n/2)) + (A^1+...+A^(n/2))*(A^(n/2))
  93. Matrix sum = tmp + tmp*a.pow(n/2);
  94. ///若n为奇数,n/2 + n/2 = n-1, 因此sum需要加上A^(n)这一项
  95. if(n & 1) sum = sum + a.pow(n);
  96. return sum;
  97. }

发表评论

表情:
评论列表 (有 0 条评论,278人围观)

还没有评论,来说两句吧...

相关阅读

    相关 UVA 11551(矩阵快速)

    题目来源:[点击打开链接][Link 1] 题目题意:题目给我们n个数和r次操作。接在输入n行,表示每次将第i个数变成它后面几个位置的和。重复r次。 题目分析:我们按照题目

    相关 快速矩阵快速

    前言 新年第一篇技术类的文章,应该算是算法方面的文章的。看标题:快速幂和矩阵快速幂,好像挺高大上。其实并不是很难,快速幂就是快速求一个数的幂(一个数的 n 次方)。