标签:
题目:一直方阵A,计算A + A^2 + A^3 + ... + A^n。
分析:分治,快速模幂。
设F(n)= A + A^2 + A^3 + ... + A^n则有;
F(n)= F(n/2)+ F(n/2)* A^(n/2)+ R;(n为奇数存在R,为A^n)
= F(n/2){E + A^(n/2)} + R;
利用递归和分治求解即可。
说明:读入的数据直接取模,否则会溢出╮(╯▽╰)╭。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; class matrix { private: int data[41][41]; public: matrix(){} matrix(int n) { for (int i = 0; i < n; ++ i) for (int j = 0; j < n; ++ j) { scanf("%d",&data[i][j]); data[i][j] %= 10; } } void show(int n) { for (int i = 0; i < n; ++ i) for (int j = 0; j < n; ++ j) { printf("%d",data[i][j]); if (j == n-1) printf("\n"); else printf(" "); }printf("\n"); } friend matrix E(matrix mat, int n); friend matrix add(matrix A, matrix B, int n); friend matrix mul(matrix A, matrix B, int n); friend matrix qpow(matrix mat, int k); friend matrix spow(matrix mat, int k); }; //单位矩阵 matrix E(matrix mat, int n) { for (int i = 0; i < n; ++ i) for (int j = 0; j < n; ++ j) mat.data[i][j] = (i==j); return mat; } //矩阵加法 matrix add(matrix A, matrix B, int n) { matrix C; for (int i = 0 ; i < n; ++ i) for (int j = 0 ; j < n; ++ j) C.data[i][j] = (A.data[i][j]+B.data[i][j])%10; return C; } //矩阵乘法 matrix mul(matrix A, matrix B, int n) { matrix C; for (int i = 0 ; i < n ; ++ i) for (int j = 0 ; j < n ; ++ j) { C.data[i][j] = 0; for (int k = 0 ; k < n ; ++ k) C.data[i][j] = (C.data[i][j]+A.data[i][k]*B.data[k][j])%10; } return C; } //矩阵快速幂 matrix qpow(matrix mat, int k, int n) { if (k == 1) return mat; matrix now = qpow(mat, k/2, n); if (k%2 == 0) return mul(now, now, n); return mul(mul(now, now, n), mat, n); } //矩阵快速幂和 matrix spow(matrix mat, int k, int n) { if (k == 1) return mat; matrix A = spow(mat, k/2, n); matrix B = add(qpow(mat, k/2, n), E(mat, n), n); if (k%2 == 0) return mul(A, B, n); else return add(mul(A, B, n), qpow(mat, k, n), n); } int main() { int n,k; while (cin >> n >> k && n) spow(matrix(n), k, n).show(n); return 0; }
标签:
原文地址:http://blog.csdn.net/mobius_strip/article/details/45652609