• P3390 【模板】矩阵快速幂


    \(P3390\) 【模板】矩阵快速幂

    题目传送门

    一、矩阵乘法介绍

    有两个矩阵:\(A\)\(B\)(矩阵实际上就是二维数组)

    \(A\)矩阵和\(B\)矩阵可以做乘法运算必须满足\(A\)矩阵的列的数量等于\(B\)矩阵的行的数量

    运算规则:\(A\)的每一行中的数字对应乘以\(B\)的每一列的数字把结果相加起来

    二、矩阵乘法模板

    1641:【例 1】矩阵 A×B
    用户名:littlehb 密码:md******22

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 110;
    int n, m, p;
    int a[N][N], b[N][N], c[N][N];
    
    //二维乘二维的矩阵乘法模板
    void mul(int c[][N], int a[][N], int b[][N]) {
        int t[N][N] = {0}; //临时数组
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                for (int k = 0; k < N; k++)
                    t[i][j] = (t[i][j] + (LL)a[i][k] * b[k][j]);
        memcpy(c, t, sizeof t);
    }
    
    int main() {
        cin >> n >> m;
        // A矩阵 n*m
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                cin >> a[i][j];
    
        // B矩阵m*p
        cin >> p;
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= p; j++)
                cin >> b[i][j];
    
        //矩阵乘法
        mul(c, a, b);
    
        //输出结果,控制格式
        for (int i = 1; i <= n; i++, puts("")) //好牛B的一个写法!
            for (int j = 1; j <= p; j++)
                printf("%d ", c[i][j]);
    
        return 0;
    }
    

    二、矩阵快速幂

    单位矩阵

    在普通的乘法中,一个数乘\(1\)还是等于它本身,在矩阵乘法中也有这么一个\(1\),它就是单位矩阵

    不同于普通乘法中的单位\(1\),对于不同矩阵他们的单位矩阵大小是不同的

    对于\(n∗m\)的矩阵,它的单位矩阵大小为\(m∗m\),对于\(m∗n\)的矩阵,它的单位矩阵大小为\(n∗n\)

    也就是说单位矩阵都是正方形的,这是因为只有正方形的矩阵能保证结果和前一个矩阵形状相同

    单位矩阵的元素非\(0\)\(1\),从左上角到右下角的对角线上元素皆为\(1\),其他皆为\(0\)

    使用单元矩阵

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MOD = 1e9 + 7;
    const int N = 110;
    LL n, k;             //本题数据范围很大,用int直接wa哭了
    LL a[N][N], b[N][N]; //原始矩阵,结果矩阵
    
    //矩阵快速幂
    
    //矩阵乘法
    void mul(LL c[][N], LL a[][N], LL b[][N]) {
        LL t[N][N] = {0};
        for (LL i = 0; i < n; i++)
            for (LL j = 0; j < n; j++)
                for (LL k = 0; k < n; k++)
                    t[i][j] = (t[i][j] + a[i][k] * b[k][j] % MOD) % MOD; //矩阵乘法
        memcpy(c, t, sizeof t);
    }
    
    int main() {
        cin >> n >> k;
        //输入原始矩阵
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                cin >> a[i][j];
    
        // 1、单位矩阵
        for (int i = 0; i < n; i++) b[i][i] = 1;
    
        // 2、计算矩阵快速幂
        for (LL i = k; i; i >>= 1) {
            if (i & 1) mul(b, b, a);
            mul(a, a, a);
        }
    
        //输出
        for (int i = 0; i < n; i++, puts(""))
            for (int j = 0; j < n; j++)
                printf("%lld ", b[i][j]);
        return 0;
    }
    

    不使用单元矩阵

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int MOD = 1e9 + 7;
    const int N = 110;
    LL n, k;             //本题数据范围很大,用int直接wa哭了
    LL a[N][N], b[N][N]; //原始矩阵,结果矩阵
    
    //矩阵乘法
    void mul(LL c[][N], LL a[][N], LL b[][N]) {
        LL t[N][N] = {0};
        for (LL i = 0; i < n; i++)
            for (LL j = 0; j < n; j++)
                for (LL k = 0; k < n; k++)
                    t[i][j] = (t[i][j] + a[i][k] * b[k][j] % MOD) % MOD; //矩阵乘法
        memcpy(c, t, sizeof t);
    }
    
    int main() {
        cin >> n >> k;
        //输入原始矩阵
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
                b[i][j] = a[i][j]; //这种解法与标准解法不同,不用构建单位矩阵
                //直接赋值初始化了一个,然后执行k-1次就完成了矩阵的k次幂
            }
        // 2、计算矩阵快速幂
        for (LL i = k - 1; i; i >>= 1) {
            if (i & 1) mul(b, b, a);
            mul(a, a, a);
        }
    
        //输出
        for (int i = 0; i < n; i++, puts(""))
            for (int j = 0; j < n; j++)
                printf("%lld ", b[i][j]);
        return 0;
    }
    
  • 相关阅读:
    C#中正则表达式的分组构造
    CompressionModule压缩模块
    BS程序代码与安全与基本攻击/防御模式
    mssql 性能优化的一些认识
    sql语句基础
    利用.net2.0中的GZip或Deflate压缩文件
    一个完整的ID生成器,并极大地降低了并发重复的概率,转换成十六进制 时间戳
    IE中的条件注释表
    DevExpress的10个使用技巧
    几种检查调试CSS布局的有效方法
  • 原文地址:https://www.cnblogs.com/littlehb/p/16039506.html
Copyright © 2020-2023  润新知