Ultraviolet A 11149-power of Matrix
Question Link
Given an N * n matrix A and K, evaluate ΣKIAI
Train of Thought: Use multiplier to implement, SigmaKIAI= (1 +AK/2) ΣK/2IAI, Continue to be split.
Code:
#include <cstdio>#include <cstring>const int N = 45;int n, k;struct mat {int v[N][N];mat() {memset(v, 0, sizeof(v));} mat operator * (mat c) { mat ans; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { ans.v[i][j] = (ans.v[i][j] + v[i][k] * c.v[k][j]) % 10; } }}return ans; } mat operator + (mat c) { mat ans; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) ans.v[i][j] = (v[i][j] + c.v[i][j]) % 10;return ans; }} A;mat pow_mod(mat x, int k) {mat ans;for (int i = 0; i < n; i++) ans.v[i][i] = 1;while (k) {if (k&1) ans = ans * x;x = x * x;k >>= 1; } return ans;}mat solve(mat x, int k) {if (k == 1) return x;mat ans;for (int i = 0; i < n; i++) ans.v[i][i] = 1;if (k == 0) return ans;ans = (ans + pow_mod(x, k>>1))* solve(x, k>>1);if (k&1) ans = ans + pow_mod(x, k);return ans;}int main() {while (~scanf("%d%d", &n, &k) && n) { for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { scanf("%d", &A.v[i][j]); A.v[i][j] %= 10; } A = solve(A, k); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) printf("%d%c", A.v[i][j], (j == n - 1 ? '\n' : ' '));printf("\n"); }return 0;}