构造矩阵解决问题 【nyoj299 Matrix Power Series】

曾经终败给现在 2022-08-12 20:28 196阅读 0赞

矩阵的又一个新用法,构造矩阵进行快速幂。

比如拿 nyoj299 Matrix Power Series 来说

给出这样一个递推式:S = A + A2 + A3 + … + Ak.

让你求s,A是一个矩阵,而k非常大。怎么办呢?

推理发现:Fn = A + A*F(n-1)

然后我们可以构造矩阵:

(Fn ,1 ) = (Fn-1 ,1) * (A,0。A,1) = (F1 , 1) * (A,0。A,1)^K-1

那么我们就可以用一个矩阵快速幂了。

下面是模板题目的代码:

  1. #include <cstdio>
  2. #include <string>
  3. #include <cmath>
  4. #include <iostream>
  5. using namespace std;
  6. int M;
  7. const long long N = 32*2;
  8. long long t,b,c,f1,f2;
  9. struct tree //基础矩阵
  10. {
  11. long long line,cal;
  12. long long a[N+1][N+1];
  13. };
  14. struct Node //构造矩阵
  15. {
  16. long long line,cal;
  17. long long a[N+1][N+1];
  18. Node(tree x)
  19. {
  20. line=x.line*2;
  21. cal=2*x.cal;
  22. for(int i=0;i<x.line*2;i++)
  23. {
  24. for(int j=0;j<x.cal;j++)
  25. {
  26. a[i][j]=x.a[i%x.line][j];
  27. }
  28. }
  29. for(int i=0;i<x.line;i++)
  30. for(int j=x.cal;j<x.cal*2;j++)
  31. a[i][j]=0;
  32. for(int i=x.line;i<2*x.line;i++){
  33. for(int j=x.cal;j<2*x.cal;j++){
  34. if(i==j)
  35. a[i][j]=1;
  36. else
  37. a[i][j]=0;
  38. }
  39. }
  40. }
  41. };
  42. Node isit(Node x,long long c) //矩阵初始化
  43. {
  44. for(long long i=0;i<N;i++)
  45. for(long long j=0;j<N;j++)
  46. x.a[i][j]=c;
  47. return x;
  48. }
  49. Node Matlab(Node x,Node s) //矩阵乘法
  50. {
  51. Node ans(x);
  52. ans.line = x.line,ans.cal = s.cal;
  53. ans=isit(ans,0);
  54. for(long long i=0;i<x.line;i++)
  55. {
  56. for(long long j=0;j<x.cal;j++)
  57. {
  58. for(long long k=0;k<s.cal;k++)
  59. {
  60. ans.a[i][j] += x.a[i][k]*s.a[k][j];
  61. ans.a[i][j]=(ans.a[i][j])%M;
  62. }
  63. }
  64. }
  65. return ans;
  66. }
  67. Node Fast_Matrax(tree x,long long n) //矩阵快速幂
  68. {
  69. Node ans(x),tmp(x);
  70. for(int i=0;i<ans.line/2;i++) //chushihua
  71. {
  72. for(int j=0;j<ans.cal;j++)
  73. {
  74. ans.a[i][j]=ans.a[i+ans.line/2][j];
  75. //printf("%d ",ans.a[i][j]);
  76. }
  77. }
  78. ans.line/=2;
  79. while(n>0)
  80. {
  81. if(n%2)
  82. {
  83. ans=Matlab(ans,tmp);
  84. }
  85. tmp=Matlab(tmp,tmp);
  86. n/=2;
  87. }
  88. return ans;
  89. }
  90. int main()
  91. {
  92. int n,k,m;
  93. while(~scanf("%d%d%d",&n,&k,&m))
  94. {
  95. M=m;
  96. tree p;
  97. p.line=n,p.cal=n;
  98. for(int i=0;i<n;i++)
  99. for(int j=0;j<n;j++)
  100. scanf("%d",&p.a[i][j]);
  101. Node ans=Fast_Matrax(p,k-1);
  102. for(int i=0;i<ans.line;i++)
  103. {
  104. for(int j=0;j<ans.cal/2;j++)
  105. printf("%d ",ans.a[i][j]);
  106. puts("");
  107. }
  108. }
  109. return 0;
  110. }

发表评论

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

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

相关阅读