题目链接:UVA 11149 Power of Matrix
题目大意:
已知(n)阶矩阵(A),求(sum_{i=1}^{k}A^i)。
题解:
定义({SUM}_i=sum_{j=1}^{i}A^j)。
构造矩阵:
[left(
egin{matrix}
A^i \
{SUM}_i
end{matrix}
ight)
=
left(
egin{matrix}
A & 0 \
A & E
end{matrix}
ight)
imes
left(
egin{matrix}
A^{i-1} \
{SUM}_{i-1}
end{matrix}
ight)
]
所以:
[left(
egin{matrix}
A^k \
{SUM}_k
end{matrix}
ight)
=
left(
egin{matrix}
A & 0 \
A & E
end{matrix}
ight)^{k-1}
imes
left(
egin{matrix}
A \
A
end{matrix}
ight)
]
题目只要求最后一位数字,则在矩阵快速幂时对(10)取余就行了。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct Matrix { // 矩阵
int row, col;
int num[85][85];
};
Matrix multiply(Matrix a, Matrix b) { // 矩阵乘法
Matrix temp;
temp.row = a.row, temp.col = b.col;
memset(temp.num, 0, sizeof(temp.num));
for (int i = 0; i < a.row; ++i)
for (int j = 0; j < b.col; ++j)
for (int k = 0; k < a.col; ++k)
temp.num[i][j] = (temp.num[i][j] + a.num[i][k] * b.num[k][j]) % 10;
return temp;
}
Matrix MatrixFastPow(Matrix base, int n, int k) { // 矩阵快速幂
Matrix ans;
ans.row = ans.col = n;
memset(ans.num, 0, sizeof(ans));
for (int i = 0; i < n; ++i) {
ans.num[i][i] = 1;
}
while (k) {
if (k & 1) ans = multiply(ans, base);
base = multiply(base, base);
k >>= 1;
}
return ans;
}
int main() {
int n, k;
while (cin >> n >> k && n) {
Matrix base, res;
base.row = base.col = 2 * n;
res.row = 2 * n, res.col = n;
memset(base.num, 0, sizeof(base.num));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
cin >> base.num[i][j];
base.num[i][j] %= 10; // 只需要最后一位
res.num[i][j] = res.num[i + n][j] = base.num[i + n][j] = base.num[i][j];
}
}
for (int i = n; i < 2 * n; ++i) {
base.num[i][i] = 1;
}
Matrix ans = multiply(MatrixFastPow(base, 2 * n, k - 1), res);
for (int i = n; i < 2 * n; ++i) {
for (int j = 0; j < n; ++j) {
cout << ans.num[i][j];
if (j != n - 1) cout << ' ';
}
cout << endl;
}
cout << endl;
}
return 0;
}