【模板】矩阵乘法

时间:2019-09-18
本文章向大家介绍【模板】矩阵乘法,主要包括【模板】矩阵乘法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

矩阵乘法基础模板:

P3390 【模板】矩阵快速幂

在矩阵快速幂中,正对角线为\(1\),其他为\(0\)的矩阵为单位矩阵。

利用单位矩阵进行快速幂。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL n, k, flag;
struct Matrix {
    LL a[105][105];
    Matrix() { memset(a, 0, sizeof(a)); }
    inline LL *operator [] (int x) { return a[x]; }
    Matrix operator * (Matrix b) {
        Matrix res;
        for(int i = 1; i <= n; i ++) {
            for(int k= 1; k <= n; k ++) {
                for(int j = 1; j <= n; j ++) {
                    (res[i][j] += a[i][k] * b[k][j]) %= mod;
                }
            }
        }
        return res;
    }
} a, base;
Matrix Matrix_ksm(Matrix x, LL y) {
    Matrix res = base;
    for( ; y ; x = x * x, y >>= 1) {
        if(y & 1) res = res * x;
    }
    return res;
}
int main() {
    cin >> n >> k;
    for(int i = 1; i <= n; i ++) {
        for(int j = 1; j <= n; j ++) {
            cin >> a[i][j];
        }
    }
    for(int i = 1; i <= n; i ++) base[i][i] = 1;
    Matrix ans = Matrix_ksm(a, k);
    for(int i = 1; i <= n;i ++) {
        for(int j = 1; j <= n; j ++) {
            cout << ans[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

P1939 【模板】矩阵加速(数列)

构造矩阵得
\[ \left[\begin{matrix}a_{n+1}\\a_{n}\\a_{n-1} \end{matrix}\right] = \left[\begin{matrix}1&0&1\\1&0&0\\0&1&0 \end{matrix}\right] * \left[\begin{matrix}a_{n}\\a_{n-1}\\a_{n-2} \end{matrix}\right] \]
套上矩阵快速幂即可

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL t, n;
struct Matrix {
    LL a[4][4];
    Matrix() { memset(a, 0, sizeof(a)); }
    inline LL *operator [] (int x) { return a[x]; }
    Matrix operator * (Matrix b) {
        Matrix res;
        for(int i = 1; i <= 3; i ++) {
            for(int k= 1; k <= 3; k ++) {
                for(int j = 1; j <= 3; j ++) {
                    (res[i][j] += a[i][k] * b[k][j]) %= mod;
                }
            }
        }
        return res;
    }
} ans, base;
void Matrix_ksm(LL y) {
    for( ; y ; base = base * base, y >>= 1) {
        if(y & 1) ans = ans * base;
    }
}
void INIT() {
    for(int i = 1; i <= 3; i ++) {
        for(int j = 1; j <= 3; j ++) {
            base[i][j] = 0;
            ans[i][j] = 0;
        }
    }
    base[1][1] = base[1][3] = base[2][1] = base[3][2] = 1;
    ans[1][1] = ans[2][1] = ans[3][1] = 1;
}
int main() {
    cin >> t;
    while(t --> 0) {
        cin >> n;
        if(n <= 3) { puts("1"); continue; }
        INIT();
        Matrix_ksm(n-1);
        cout << ans[1][1] << endl;
    }
    return 0;
}

P1962 斐波那契数列

构造矩阵得
\[ \left[\begin{matrix}f_{n}\\f_{n-1}\end{matrix}\right] = \left[\begin{matrix}1&1\\1&0 \end{matrix}\right] * \left[\begin{matrix}f_{n-1}\\f_{n-2}\end{matrix}\right] \]
同样套上矩阵快速幂即可

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
LL n;
struct Matrix {
    LL a[3][3];
    Matrix() { memset(a, 0, sizeof(a)); }
    inline LL *operator[] (int x) { return a[x]; }
    Matrix operator * (Matrix b) {
        Matrix res;
        for(int i = 1; i <= 2; i ++) {
            for(int k = 1; k <= 2; k ++) {
                for(int j = 1; j <= 2; j ++) {
                    (res[i][j] += a[i][k] * b[k][j]) %= mod;
                }
            }
        }
        return res;
    }
} ans, base;
void Matrix_ksm(LL y) {
    for( ; y ; base = base * base, y >>= 1)
        if(y & 1) ans = ans * base;
}
void INIT() {
    base[1][1] = base[1][2] = base[2][1] = 1;
    ans[1][1] = ans[1][2] = 1;
}
int main() {
    cin >> n;
    if(n <= 2) return puts("1"), 0;
    INIT();
    Matrix_ksm(n-2);
    printf("%lld\n", ans[1][1]);
    return 0;
}

一般构造矩阵的方法就是\(rand()\), 使劲\(rand()\).

原文地址:https://www.cnblogs.com/Paranoid-LS/p/11545440.html