快速矩阵幂

/***************************************************** > File Name: matrix_factorial.cpp > Author: Yuji CAO > Mail: [email protected] > Created Time: 六 6/10 13:30:07 2017 *****************************************************/

#include<map>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<list>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<set>
using namespace std;
typedef vector<vector<int> > matrix;
class matrix_pow {
public:
    /** * 矩阵乘法 **/
    static matrix mul(const matrix& left, const matrix& right) {
        matrix ret = matrix_pow::mk_zero((int)left.size(), (int)right.size());
        for (int i = 0; i < left.size(); ++i) {
            for (int j = 0; j < right[0].size(); ++j) {
                int tmp = 0;
                for (int k = 0; k < left[i].size(); ++k) {
                    tmp += left[i][k] * right[k][j];
                }
                ret[i][j] = tmp;
            }
        }
        return ret;
    }
    /** * 构造零矩阵 **/
    static matrix mk_zero(int n, int m) {
        return vector<vector<int> >(n, vector<int>(m, 0));
    }
    /** * 构造单元矩阵 **/
    static matrix mk_unit(int n) {
        matrix ret = vector<vector<int> >(n, vector<int>(n, 0));
        for (int i = 0; i < n; ++i) {
            ret[i][i] = 1;
        }
        return ret;
    }
    /** * 快速矩阵幂 **/
    matrix pow(matrix& A, int n) {
        matrix tmp = A;
        matrix ret = matrix_pow::mk_unit((int)A.size());
        while (n) {
            if (n & 1) {
                ret = matrix_pow::mul(ret, tmp); //
            }
            tmp = matrix_pow::mul(tmp, tmp); //求A^1,A^2,A^4,...,A^n
            n = n >> 1;
        }
        return ret;
    }
};

int main() {
    matrix_pow mp;
    int s;
    cin>>s;
    matrix A(s, vector<int>(s, 0));
    for (int i = 0; i < s; ++i) {
        for (int j = 0; j < s; ++j) {
            cin>>A[i][j];
        }
    }
    int n;
    cin>>n;
    matrix ret = mp.pow(A, n);
    for (int i = 0; i < s; ++i) {
        for (int j = 0; j < s; ++j) {
            cout<<ret[i][j]<<"\t";
        }
        cout<<endl;
    }
    return 0;
}
点赞