DefaultMatrix Power Series
Time limit:3000 Ms |
|
Memory limit:131072 K |
Total submissions:15553 |
|
Accepted:6658 |
Description GivenN×NMatrixAAnd a positive integerK, Find the sumS=A+A2 +A3 +... +AK. Input The input contains exactly one test case. The first line of input contains three positive integersN(N≤ 30 ),K(K≤ 109) andM(M<104). Then followNLines each containingNNonnegative integers below 32,768, givingA'S elements in row-Major Order. Output Output the elementsSModuloMIn the same wayAIs given. Sample Input 2 2 40 11 1 Sample output 1 22 3 Source |
Question: give an n * n matrix A, and find a + A ^ 2 + A ^ 3 + ...... + What is the result of a ^ K mod m?
Method 1: two decimal points
SK = a + A2 + A3 +... + AK
= (1 + a ^ (K/2) * (a + A ^ 2 + A ^ 3 +... + A ^ (K/2) + {A ^ k}
= (1 + a ^ (K/2) * (S (K/2) + {AK} When k is an even number, no {AK}
That is
K % 2 = 0: s [k] = f [k/2] (1 + a [k/2]);
K % 2 = 1: s [k] = f [k-1] + A [k];
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 32;struct Matrix { int mat[N][N]; Matrix() { memset(mat, 0, sizeof(mat)); for(int i = 0; i < N; i++) mat[i][i] = 1; }} E;int n, k, mod;Matrix Multi(Matrix a, Matrix b) { Matrix res; for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { res.mat[i][j] = 0; for(int k = 0; k < n; k++) res.mat[i][j] = (res.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod; } } return res;}Matrix Add(Matrix a, Matrix b) { Matrix res; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) res.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % mod; return res;}Matrix Pow(Matrix a, int n) { Matrix res; while(n) { if(n&1) res = Multi(res, a); a = Multi(a, a); n >>= 1; } return res;}Matrix Get_Ans(Matrix a, int k) { if(k == 1) return a; if(k&1) return Add(Pow(a, k), Get_Ans(a, k-1)); if(k % 2 == 0) { Matrix A = Get_Ans(a, k/2); Matrix B = Pow(a, k/2); Matrix C = Multi(A, B); return Add(C, A); }}int main() { Matrix A; while(~scanf("%d%d%d", &n, &k, &mod)) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { scanf("%d", &A.mat[i][j]); A.mat[i][j] %= mod; } Matrix ans = Get_Ans(A, k); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(j) printf(" "); printf("%d", ans.mat[i][j]); } printf("\n"); } } return 0;}
Method 2:
Construct a new matrix B = | A E |
| 0 E |
Then B ^ (k + 1) = | a ^ (k + 1) a ^ K + A ^ (k-1) + ...... + A ^ 2 + A + 1 |
| 0 E |
Therefore, you can use the Matrix to quickly obtain the power of B ^ (k + 1), and then subtract the unit matrix from the part in the upper left corner to obtain the final required matrix.
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 61;int n, mod, k;struct Matrix { int mat[N][N]; Matrix() { memset(mat, 0, sizeof(mat)); for(int i = 0; i < N; i++) mat[i][i] = 1; }};Matrix Multi(Matrix a, Matrix b) { Matrix res; memset(res.mat, 0, sizeof(res.mat)); for(int i = 0; i < n * 2; i++) { for(int k = 0; k < n * 2; k++) { if(a.mat[i][k]) { for(int j = 0; j < n * 2; j++) { res.mat[i][j] += a.mat[i][k] * b.mat[k][j]; res.mat[i][j] %= mod; } } } } return res;}Matrix Pow(Matrix x, int m) { Matrix res; while(m) { if(m&1) res = Multi(res, x); x = Multi(x, x); m >>= 1; } return res;}int main() { Matrix A; while(~scanf("%d%d%d",&n, &k, &mod)) { memset(A.mat, 0, sizeof(A.mat)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { scanf("%d", &A.mat[i][j]); A.mat[i][j] %= mod; } A.mat[i][i+n] = 1; } for(int i = n; i < 2 * n; i++) A.mat[i][i] = 1; Matrix ans = Pow(A, k + 1); for(int i = 0; i < n; i++) { for(int j = n; j < n * 2; j++) { if(j > n) printf(" "); if(j - i == n) printf("%d", (ans.mat[i][j] - 1 + mod) % mod); else printf("%d", ans.mat[i][j]); } printf("\n"); } } return 0;}
Poj 3233 matrix power series (matrix power)