矩阵幂求和
题意:
给矩阵A,求Σi=(1,k) Ai
SOL:
虽然可以快速幂,然而还是会炸,那么我们就优化一下。。。
若k是偶数,则S=(1+1^(k/2))(A^1+A^2+……+A^(k/2))
若k是奇数,则S=(1+1^(k/2))(A^1+A^2+……+A^(k/2))+A^k
像是快速幂套快速幂。。。。复杂度。。一个log还是两个log呢。。
Code:
#include <iostream> #include <cstdio> using namespace std; int n, m; struct Matrix { int x[31][31]; }; void matrixPrint(Matrix mat) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (j > 0) printf(" "); printf("%d", mat.x[i][j]); } printf("\n"); } } Matrix matrixMultiply(Matrix a, Matrix b) { Matrix ret; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { ret.x[i][j] = 0; for (int t = 0; t < n; ++t) { ret.x[i][j] += a.x[i][t] * b.x[t][j]; if (ret.x[i][j] >= m) ret.x[i][j] %= m; } } } return ret; } Matrix matrixPow(Matrix mat, int p) { Matrix ret; Matrix tmp = mat; for (int i = 0; i < n; ++i) { ret.x[i][i] = 1; for (int j = i + 1; j < n; ++j) { ret.x[i][j] = 0; ret.x[j][i] = 0; } } while (p > 0) { if (p & 1) ret = matrixMultiply(ret, tmp); p >>= 1; tmp = matrixMultiply(tmp, tmp); } return ret; } Matrix matrixSummary(Matrix mat, int k) { for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (mat.x[i][j] >= m) mat.x[i][j] %= m; } } if (k == 1) return mat; Matrix M1 = matrixPow(mat, k / 2); for (int i = 0; i < n; ++i) { M1.x[i][i] += 1; } Matrix M2 = matrixSummary(mat, k / 2); Matrix ret = matrixMultiply(M1, M2); if (k & 1) { Matrix tmp = matrixPow(mat, k); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { ret.x[i][j] += tmp.x[i][j]; if (ret.x[i][j] >= m) ret.x[i][j] %= m; } } } return ret; } int main() { Matrix mat; int k; scanf("%d%d%d", &n, &k, &m); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { scanf("%d", &mat.x[i][j]); } } Matrix ret = matrixSummary(mat, k); matrixPrint(ret); return 0; }
貌似还有更牛逼的。。。到时候再学下好了。。。
Sometimes it s the very people who no one imagines anything of. who do the things that no one can imagine.