[关闭]
@wsndy-xx 2018-05-20T07:50:12.000000Z 字数 1931 阅读 773

hdoj 4965 Fast Matrix Calculation

题解


题面

给定矩阵
定义矩阵
计算 的每个元素 %6 以后的和

考虑矩阵快速幂

那么矩阵
每次乘法的时间复杂度为
整个算法的时间复杂度为
显然无法接受

继续考虑优化算法
由于满足结合律

那么矩阵


在计算 时间复杂度为
然后计算 时间复杂度为
然后计算 时间复杂度为
整个算法的时间复杂度为

Code

写的有点啰嗦

  1. #include <bits/stdc++.h>
  2. const int N = 1e3 + 10;
  3. const int K = 10, Mod = 6;
  4. #define LL long long
  5. LL A[N][K], B[K][N], E[K][K], G[N][K], Answer[N][N], n, k, Pow;
  6. struct Node {
  7. LL m[10][10];
  8. Node() {memset(m, 0, sizeof m);}
  9. void Clear() {for(int i = 1; i <= 7; i ++) m[i][i] = 1;}
  10. };
  11. Node Use;
  12. void Get_k_k() {
  13. for(int i = 1; i <= k; i ++)
  14. for(int j = 1; j <= k; j ++)
  15. for(int r = 1; r <= n; r ++)
  16. Use.m[i][j] += B[i][r] * A[r][j];
  17. }
  18. Node operator * (const Node &a, const Node &b) {
  19. Node ret;
  20. for(int i = 1; i <= k; i ++)
  21. for(int j = 1; j <= k; j ++)
  22. for(int r = 1; r <= k; r ++)
  23. ret.m[i][j] = (ret.m[i][j] + a.m[i][r] * b.m[r][j]) % Mod;
  24. return ret;
  25. }
  26. void Debug(Node a) {
  27. for(int i = 1; i <= k; i ++) {
  28. for(int j = 1; j <= k; j ++)
  29. std:: cout << a.m[i][j] << " ";
  30. std:: cout << "\n";
  31. }
  32. exit(0);
  33. }
  34. Node Ksm(Node a, int pow) {
  35. Node ret; ret.Clear();
  36. while(pow) {
  37. if(pow & 1) ret = ret * a;
  38. a = a * a;
  39. pow >>= 1;
  40. }
  41. return ret;
  42. }
  43. void Get_E(Node a) {
  44. for(int i = 1; i <= k; i ++)
  45. for(int j = 1; j <= k; j ++)
  46. E[i][j] = a.m[i][j];
  47. }
  48. void Work_nk() {
  49. for(int i = 1; i <= n; i ++)
  50. for(int j = 1; j <= k; j ++)
  51. for(int r = 1; r <= k; r ++)
  52. G[i][j] = (G[i][j] + A[i][r] * E[r][j] % Mod) % Mod;
  53. }
  54. void Work_kn() {
  55. for(int i = 1; i <= n; i ++)
  56. for(int j = 1; j <= n; j ++)
  57. for(int r = 1; r <= k; r ++)
  58. Answer[i][j] = (Answer[i][j] + G[i][r] * B[r][j] % Mod) % Mod;
  59. }
  60. int Get_Answer() {
  61. int ret(0);
  62. for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) ret += Answer[i][j];
  63. return ret;
  64. }
  65. int main() {
  66. while(1) {
  67. memset(E, 0, sizeof E);
  68. memset(G, 0, sizeof G);
  69. memset(Answer, 0, sizeof Answer);
  70. memset(Use.m, 0, sizeof Use.m);
  71. std:: cin >> n >> k;
  72. if(!n && !k) break;
  73. for(int i = 1; i <= n; i ++) for(int j = 1; j <= k; j ++) std:: cin >> A[i][j];
  74. for(int i = 1; i <= k; i ++) for(int j = 1; j <= n; j ++) std:: cin >> B[i][j];
  75. Get_k_k();
  76. Pow = n * n - 1;
  77. Node Ans = Ksm(Use, Pow);
  78. Get_E(Ans);
  79. Work_nk();
  80. Work_kn();
  81. std:: cout << Get_Answer() << "\n";
  82. }
  83. return 0;
  84. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注