zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    在遇到一些递推式时,如果我们直接按公式一步步进行运算,效率较低。构造矩阵进行快速运算,可以高效地解决这个问题。

    以int型方阵为例:

    矩阵结构:

    struct Mat{
        int mat[n][n];
    };

    矩阵乘法:

    Mat mul(Mat A,Mat B)
    {
        Mat ret;
        memset(ret.mat,0,sizeof(ret));
        for(int i = 0; i<n; ++i)
            for(int j = 0; j<n; ++j)
                for(int k = 0; k<n; ++k)
                    ret.mat[i][j] += A.mat[i][k]*B.mat[k][j];
        return ret;
    }

    快速计算方阵a的k次幂:

    Mat matquickpow(Mat A,int k)
    {
        Mat ret;
        for(int i = 0; i<n; ++i)
            for(int j = 0; j<n; ++j)
                ret.mat[i][j] = (i == j);   //初始化为单位矩阵
        while(k){
            if(k&1)
                ret = mul(ret,A);
            A = mul(A,A);
            k >>= 1;
        }
        return ret;
    }

    快速计算方阵a的k次幂对mod取模的一步运算:

    Mat mulmod(Mat A,Mat B,int mod)
    {
        Mat ret;
        memset(ret.mat,0,sizeof(ret));
        for(int i = 0; i<n; ++i)
            for(int j = 0; j<n; ++j)
                for(int k = 0; k<n; ++k)
                    ret.mat[i][j] = (ret.mat[i][j]+A.mat[i][k]*B.mat[k][j])%mod;
                    //对于某些题目,当结果为负数不合题意时,可以对最终结果进行处理
                    //或者将此处改为ret.mat[i][j] = ((ret.mat[i][j]+a[i][k]*b[k][j])%mod+mod)%mod;
        return ret;
    }

    快速计算方阵a的k次幂对mod取模:

    Mat matquickpowmod(Mat A,int k,int m)
    {
        Mat ret;
        for(int i = 0; i<n; ++i)
            for(int j = 0; j<n; ++j)
                ret.mat[i][j] = (i == j);   //初始化为单位矩阵
        while(k){
            if(k&1)
                ret = mulmod(ret,A);
            A = mulmod(A,A);
            k >>= 1;
        }
        return ret;
    }

    例如,对于斐波那契数列的递推部分,我们可以运用矩阵快速幂进行计算:

    将Fn+2 = Fn+Fn+1转换为

    就可以运用矩阵快速幂进行计算了。

  • 相关阅读:
    Linux命令——tac、rev
    Linux命令——pr
    Linux命令——column
    【问题】显示每个用户近期登陆系统次数
    Git分支
    如何使用Systemctl管理系统服务和单元?
    IPTables 和 Netfilter 框架
    Nginx安装及配置
    WMware Workstation——时间和时区问题
    WMware Workstation——网络类型:NAT、bridge、host-only
  • 原文地址:https://www.cnblogs.com/inmoonlight/p/5259912.html
Copyright © 2011-2022 走看看