• 矩阵乘法


    矩阵乘法

      对于矩阵A(m*n)和一个矩阵B(n*p)相乘可以得到一个矩阵C(m*p),定义如下

      

      矩阵乘法满足结合律和分配率,但不满足交换律。

    矩阵乘法加速递推

      矩阵乘法中一种特殊的情形,F是一个1*n的矩阵,A是一个n*n的矩阵,F'=F*A也是一个1*n的矩阵。F和F'可看作一维数组,省略他们的行下标1。按照矩阵乘法的定义,任意的 j ∈ [1, n] ,有表示的含义是,进过一次与A的矩阵乘法后,F数组中第k个值会以A[k][j]为系数累加到F'数组上第j个值上,等价于在一个向量的k, j两个状态之间发生了递推。

      所以我们可以利用矩阵乘法加速递推。

      所以对于具有以下特点的题,我们可以利用矩阵加速乘法来加速递推:

      1. 可以抽象为一个长度为n的一维向量,该项量在每个单位时间内只发生一次变化。
      2. 变化的形式是线性递推(只有若干“加法”或“乘以一个系数“的运算)。
      3. 该递推式在每个时间可能作用于不同的数据上,但本身保持不变。
      4. 向量的变化时间(即递推轮)很长,但向量长度n很小。

      我们在这儿做出以下定义

      1. 状态矩阵:长度为n的一维向量。
      2. 转移矩阵:用于与状态矩阵相乘的固定不变的矩阵A。

      如若状态矩阵的第x个数对下一个单位时间的状态矩阵的第y个矩阵产生影响,我们就把转移矩阵的A[x][y]处赋予适当的系数,然后用矩阵快速幂完成。

    矩阵快速幂

     1 struct Matrix
     2 {
     3     int Transition_Matrix[][] ;
     4     Matrix friend operator * (Matrix a, Matrix b)
     5         {
     6             Matrix c;
     7             memset(c.Transition_Matrix, 0, sizeof(c.Transition_Matrix));
     8             for(int i = 0; i < 16; ++ i)
     9                 for(int j = 0; j < 16; ++ j)
    10                     for(int k = 0; k < 16; ++ k)
    11                         c.Transition_Matrix[i][j] = (c.Transition_Matrix[i][j] + a.Transition_Matrix[i][k] * b.Transition_Matrix[k][j] % mod) % mod;
    12             return c;
    13         }
    14     Matrix friend operator % (Matrix a, int mod)
    15         {
    16             for(int i = 1; i < 16; ++ i)
    17                 for(int j = 1; j < 16; ++ j)
    18                     a.Transition_Matrix[i][j] = a.Transition_Matrix[i][j] % mod;
    19             return a;
    20         }
    21     Matrix ksm(Matrix a, int b)
    22     {
    23         Matrix res;
    24         memset(res.Transition_Matrix, 0, sizeof(res));
    25         for(int i = 0; i < 16; ++ i)    res.Transition_Matrix[i][i] = 1;
    26         for(;b; b >>= 1, a = (a * a) % mod)
    27             if(b & 1)    res = (res * a) % mod;
    28         return res;     
    29     }
    30 };
  • 相关阅读:
    JSONObject,JSONArray,Map,String之间转换
    linux下,一个运行中的程序,究竟占用了多少内存
    利用VMware在虚拟机上安装Zookeeper集群
    30岁后职场改变
    Zookeeper客户端 CuratorFramework使用
    oracle 用户与表空间关系
    Docker Rest API使用入门
    docker 远程rest api 访问配置
    Oracle 用户、角色管理简介
    Oracle 参数文件及相关操作介绍
  • 原文地址:https://www.cnblogs.com/2020pengxiyue/p/9291349.html
Copyright © 2020-2023  润新知