题意:给一个n×n的矩阵A,求S = A + A2 + A3 + … + Ak。
解法:从式子中可得递推式S(n) = S(n - 1) + An,An = An-1×A,可得矩阵递推式
[S(n), An] = [S(n - 1), An-1] * [1 0]
[A A] <-orz画不出二维矩阵了
初始状态S(0)为0矩阵,A0为单位矩阵,跑一下矩阵快速幂……
矩阵运算写屎了……调了一下午bugQAQ……矩阵套矩阵什么的好讨厌啊……
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #include<iomanip> #define LL long long #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 using namespace std; struct node { int a[35][35]; }matrix; int n = 2, m = 100; node mul(node a, node b) { node res; memset(res.a, 0, sizeof res.a); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { int tmp = 0; for(int k = 0; k < n; k++) { tmp += a.a[i][k] * b.a[k][j]; tmp %= m; } res.a[i][j] = tmp; } return res; } void ADD(node &a, node b) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { a.a[i][j] += b.a[i][j]; a.a[i][j] %= m; } } void MUL(node a[][2], node b[][2], int x) { node res[2][2]; for(int i = 0; i < x; i++) for(int j = 0; j < 2; j++) { node tmp; memset(tmp.a, 0, sizeof tmp.a); for(int k = 0; k < 2; k++) ADD(tmp, mul(a[i][k], b[k][j])); res[i][j] = tmp; } for(int i = 0; i < x; i++) for(int j = 0; j < 2; j++) a[i][j] = res[i][j]; } node POW(int k) { node base[2][2]; memset(base[0][0].a, 0, sizeof base[0][0].a); for(int i = 0; i < n; i++) base[0][0].a[i][i] = 1; memset(base[0][1].a, 0, sizeof base[0][1].a); base[1][1] = base[1][0] = matrix; node x[1][2]; memset(x[0][0].a, 0, sizeof x[0][0].a); memset(x[0][1].a, 0, sizeof x[0][1].a); for(int i = 0; i < n; i++) x[0][1].a[i][i] = 1; while(k) { if(k & 1) MUL(x, base, 1); k >>= 1; MUL(base, base, 2); } return x[0][0]; } int main() { int k; while(~scanf("%d%d%d", &n, &k, &m)) { for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { scanf("%d", &matrix.a[i][j]); matrix.a[i][j] %= m; } node ans = POW(k); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(j) printf(" "); printf("%d", ans.a[i][j]); } puts(""); } } return 0; }