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转换为

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

  • 相关阅读:
    poj 1840(五元三次方程组)
    Selenium(二)开发环境的搭建
    Selenium(一)自动化测试简介
    (二)AppScan使用教程
    (一)AppScan的安装及破解
    (一)python3.7的安装
    读完《大道至简》后的反思
    BZOJ3585: mex
    BZOJ3544: [ONTAK2010]Creative Accounting
    BZOJ3531: [Sdoi2014]旅行
  • 原文地址:https://www.cnblogs.com/inmoonlight/p/5259912.html
Copyright © 2011-2022 走看看