poj3233(矩阵快速幂)

poj3233 http://poj.org/problem?id=3233

给定n ,k,m

然后是n*n行,

我们先可以把式子转化为递推的,然后就可以用矩阵来加速计算了。  矩阵是加速递推计算的一个好工具

poj3233(矩阵快速幂)

我们可以看到,矩阵的每个元素都是一个矩阵,其实这计算一个分块矩阵,我们可以把分块矩阵展开,它的乘法和普通矩阵的乘法是一样的。

  1 #include <stdio.h>

  2 #include <string.h>

  3 #include <stdlib.h>

  4 #include <algorithm>

  5 #include <iostream>

  6 #include <queue>

  7 #include <stack>

  8 #include <vector>

  9 #include <map>

 10 #include <set>

 11 #include <string>

 12 #include <math.h>

 13 using namespace std;

 14 #pragma warning(disable:4996)

 15 typedef long long LL;

 16 const int INF = 1 << 30;

 17 int MOD;

 18 /*

 19 矩阵的元素是矩阵,即分块矩阵

 20 分块矩阵的乘法和普通矩阵的乘法是一样的

 21 */

 22 struct Matrix

 23 {

 24     int mat[66][66];

 25     int size;

 26     Matrix(int n)

 27     {

 28         size = n;

 29     }

 30     void makeZero()

 31     {

 32         for (int i = 0; i < size; ++i)

 33         {

 34             for (int j = 0; j < size; ++j)

 35                 mat[i][j] = 0;

 36         }

 37     }

 38     void makeUnit()

 39     {

 40         for (int i = 0; i < size; ++i)

 41         {

 42             for (int j = 0; j < size; ++j)

 43                 mat[i][j] = (i == j);

 44         }

 45     }

 46 };

 47 

 48 Matrix operator*(const Matrix &lhs, const Matrix &rhs)

 49 {

 50     Matrix ret(lhs.size);

 51     ret.makeZero();

 52     for (int i = 0; i < lhs.size; ++i)

 53     {

 54         for (int j = 0; j < lhs.size; ++j)

 55         {

 56             for (int k = 0; k < lhs.size; ++k)

 57             {

 58                 ret.mat[i][j] += (lhs.mat[i][k] * rhs.mat[k][j]);

 59                 if (ret.mat[i][j] >= MOD)

 60                     ret.mat[i][j] %= MOD;

 61             }

 62         }

 63     }

 64     return ret;

 65 }

 66 Matrix operator^(Matrix &a, int k)

 67 {

 68     Matrix ret(a.size);//单位矩阵

 69     ret.makeUnit();

 70     while (k)

 71     {

 72         if (k & 1)

 73         {

 74             ret = ret * a;

 75         }

 76         a = a * a;

 77         k >>= 1;

 78     }

 79     return ret;

 80 }

 81 int main()

 82 {

 83     int n, k, m, i, j;

 84     while (scanf("%d%d%d", &n, &k, &MOD) != EOF)

 85     {

 86         Matrix a(2*n);

 87         Matrix tmp(2*n);;

 88         a.makeZero();

 89         for (i = 0; i < n; ++i)

 90         {

 91             for (j = 0; j < n; ++j)

 92             {

 93                 scanf("%d", &a.mat[i][j]);

 94                 if (a.mat[i][j] >= MOD)

 95                     a.mat[i][j] %= MOD;

 96                 tmp.mat[i][j] = a.mat[i][j];

 97                 tmp.mat[i][n + j] = a.mat[i][j];

 98             }

 99             a.mat[n + i][i] = a.mat[n + i][n + i] = 1;

100         }

101         a = a ^ (k - 1);

102         Matrix ans(2*n);

103         ans.makeZero();

104         m = 2 * n;

105         for (i = 0; i < n; ++i)

106         {

107             for (j = 0; j < n; ++j)

108             {

109                 for (k = 0; k < m; ++k)

110                 {

111                     ans.mat[i][j] += tmp.mat[i][k] * a.mat[k][j];

112                     if (ans.mat[i][j] >= MOD)

113                         ans.mat[i][j] %= MOD;

114                 }

115             }

116         }

117         for (i = 0; i < n; ++i)

118         {

119             for (j = 0; j < n; ++j)

120             {

121                 j == n - 1 ? printf("%d\n", ans.mat[i][j]) : printf("%d ", ans.mat[i][j]);

122             }

123         }

124     }

125     return 0;

126 }
View Code

 

当然了,我们还可以用二分的方法方法来计算

poj3233(矩阵快速幂)

  1 #include <stdio.h>

  2 #include <string.h>

  3 #include <stdlib.h>

  4 #include <algorithm>

  5 #include <iostream>

  6 #include <queue>

  7 #include <stack>

  8 #include <vector>

  9 #include <map>

 10 #include <set>

 11 #include <string>

 12 #include <math.h>

 13 using namespace std;

 14 #pragma warning(disable:4996)

 15 typedef long long LL;

 16 const int INF = 1 << 30;

 17 int MOD;

 18 /*

 19 矩阵的元素是矩阵,即分块矩阵

 20 分块矩阵的乘法和普通矩阵的乘法是一样的

 21 */

 22 struct Matrix

 23 {

 24     int mat[66][66];

 25     int size;

 26     Matrix(int n)

 27     {

 28         size = n;

 29     }

 30     void makeZero()

 31     {

 32         for (int i = 0; i < size; ++i)

 33         {

 34             for (int j = 0; j < size; ++j)

 35                 mat[i][j] = 0;

 36         }

 37     }

 38     void makeUnit()

 39     {

 40         for (int i = 0; i < size; ++i)

 41         {

 42             for (int j = 0; j < size; ++j)

 43                 mat[i][j] = (i == j);

 44         }

 45     }

 46 };

 47 

 48 Matrix operator*(const Matrix &lhs, const Matrix &rhs)

 49 {

 50     Matrix ret(lhs.size);

 51     ret.makeZero();

 52     for (int i = 0; i < lhs.size; ++i)

 53     {

 54         for (int j = 0; j < lhs.size; ++j)

 55         {

 56             for (int k = 0; k < lhs.size; ++k)

 57             {

 58                 ret.mat[i][j] += (lhs.mat[i][k] * rhs.mat[k][j]);

 59                 if (ret.mat[i][j] >= MOD)

 60                     ret.mat[i][j] %= MOD;

 61             }

 62         }

 63     }

 64     return ret;

 65 }

 66 Matrix operator^(Matrix &a, int k)

 67 {

 68     Matrix ret(a.size);//单位矩阵

 69     ret.makeUnit();

 70     while (k)

 71     {

 72         if (k & 1)

 73         {

 74             ret = ret * a;

 75         }

 76         a = a * a;

 77         k >>= 1;

 78     }

 79     return ret;

 80 }

 81 Matrix operator+(const Matrix &lhs, const Matrix &rhs)

 82 {

 83     Matrix ret(lhs.size);

 84     ret.makeZero();

 85     for (int i = 0; i < lhs.size; ++i)

 86     {

 87         for (int j = 0; j < lhs.size; ++j)

 88         {

 89             ret.mat[i][j] = lhs.mat[i][j] + rhs.mat[i][j];

 90             if (ret.mat[i][j] >= MOD)

 91                 ret.mat[i][j] %= MOD;

 92         }

 93     }

 94     return ret;

 95 }

 96 Matrix matrixSum(Matrix a, int k)

 97 {

 98     if (k == 1)

 99         return a;

100     Matrix ret = matrixSum(a, k / 2);

101     if (k & 1)

102     {

103         Matrix tmp = a ^ (k / 2 + 1);

104         ret = ret * tmp + ret + tmp;

105     }

106     else

107     {

108         Matrix tmp = a ^ (k / 2);

109         ret = ret*tmp + ret;

110     }

111     return ret;

112 }

113 int main()

114 {

115     int n, k, m, i, j;

116     while (scanf("%d%d%d", &n, &k, &MOD) != EOF)

117     {

118         Matrix a(n);

119         for (i = 0; i < n; ++i)

120         {

121             for (j = 0; j < n; ++j)

122             {

123                 scanf("%d", &a.mat[i][j]);

124                 if (a.mat[i][j] >= MOD)

125                     a.mat[i][j] %= MOD;

126             }

127         }

128         Matrix ans = matrixSum(a, k);

129         for (i = 0; i < n; ++i)

130         {

131             for (j = 0; j < n; ++j)

132                 j == n - 1 ? printf("%d\n", ans.mat[i][j]) : printf("%d ", ans.mat[i][j]);

133         }

134         return 0;

135     }

136 }
View Code

 

你可能感兴趣的:(poj)