【矩阵快速幂+二分】Matrix Power Series POJ - 3233

╰半夏微凉° 2022-06-10 10:23 269阅读 0赞

Think:
1知识点:矩阵快速幂+二分求解等比矩阵前n项和
2题意:输入一个矩阵,求解矩阵前n项和(S = A^1 + A^2 + A^3 + … + A^k.),模mod

vjudge题目链接

以下为Accepted代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int N = 40;
  6. typedef struct Matrax{
  7. int m[N][N];
  8. }matrax;
  9. matrax e, per;
  10. int n, m, mod;
  11. void read();/*读取矩阵+初始化单位矩阵*/
  12. matrax Add(matrax a, matrax b);/*矩阵加法*/
  13. matrax multi(matrax a, matrax b);/*矩阵乘法*/
  14. matrax power(int k);/*矩阵快速幂*/
  15. matrax matrax_sum(int k);/*等比矩阵前n项和*/
  16. void Pri(matrax ans);/*输出矩阵*/
  17. int main(){
  18. while(~scanf("%d %d %d", &n, &m, &mod)){
  19. read();
  20. matrax ans = matrax_sum(m);
  21. Pri(ans);
  22. }
  23. return 0;
  24. }
  25. void read(){
  26. /*读取矩阵+初始化单位矩阵*/
  27. for(int i = 0; i < n; i++){
  28. for(int j = 0; j < n; j++){
  29. scanf("%d", &e.m[i][j]);
  30. e.m[i][j] %= mod;
  31. per.m[i][j] = (i == j);
  32. }
  33. }
  34. }
  35. matrax Add(matrax a, matrax b){
  36. /*矩阵加法*/
  37. matrax c;
  38. for(int i = 0; i < n; i++){
  39. for(int j = 0; j < n; j++){
  40. c.m[i][j] = (a.m[i][j] + b.m[i][j])%mod;
  41. }
  42. }
  43. return c;
  44. }
  45. matrax multi(matrax a, matrax b){
  46. /*矩阵乘法*/
  47. matrax c;
  48. for(int i = 0; i < n; i++){
  49. for(int j = 0; j < n; j++){
  50. c.m[i][j] = 0;
  51. for(int k = 0; k < n; k++){
  52. c.m[i][j] += (a.m[i][k] * b.m[k][j])%mod;
  53. }
  54. c.m[i][j] %= mod;
  55. }
  56. }
  57. return c;
  58. }
  59. matrax power(int k){
  60. /*矩阵快速幂*/
  61. matrax p, ans = per;
  62. p = e;
  63. while(k){
  64. if(k & 1)
  65. ans = multi(ans, p);
  66. p = multi(p, p);
  67. k >>= 1;
  68. }
  69. return ans;
  70. }
  71. matrax matrax_sum(int k){
  72. /*等比矩阵前n项和*/
  73. if(k == 1)
  74. return e;
  75. matrax tmp, b;
  76. tmp = matrax_sum(k>>1);
  77. if(k & 1){
  78. b = power((k>>1)+1);
  79. tmp = Add(tmp, multi(b, tmp));
  80. tmp = Add(tmp, b);
  81. }
  82. else {
  83. b = power(k>>1);
  84. tmp = Add(tmp, multi(b, tmp));
  85. }
  86. return tmp;
  87. }
  88. void Pri(matrax ans){
  89. /*输出矩阵*/
  90. for(int i = 0; i < n; i++){
  91. for(int j = 0; j < n; j++){
  92. printf("%d%c", ans.m[i][j], j == n-1? '\n': ' ');
  93. }
  94. }
  95. }

发表评论

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

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

相关阅读