浅谈矩阵乘法

先来一段百科

矩阵乘法是一种高效的算法,可以把一些一维递推优化到log(n ),还可以求路径方案等,所以更是一种应用性极强的算法。矩阵,是线性代数中的基本概念之一。一个m×n的矩阵就是m×n个数排成m行n列的一个数阵。由于它把许多数据紧凑的集中到了一起,所以有时候可以简便地表示一些复杂的模型。矩阵乘法看起来很奇怪,但实际上非常有用,应用也十分广泛。一个矩阵说穿了就是一个二维数组。一个n行m列的矩阵可以乘以一个m行p列的矩阵,得到的结果是一个n行p列的矩阵,其中的第i行第j列位置上的数等于前一个矩阵第i行上的m个数与后一个矩阵第j列上的m个数对应相乘后所有m个乘积的和。 ——by 互动百科

怎么说呢,反正这个东西可以加快某些算法或者运算的速度
一般配合矩阵快速幂使用
关于如何相乘,其实上面的百科说的已经很清楚了
具体实现如下:

inline juzhen cheng(juzhen a,juzhen b){
    memset(z.a,0,sizeof z.a);
    for(ll i=1;i<=2;i++)
        for(ll j=1;j<=2;j++)
            for(ll k=1;k<=2;k++)z.a[i][j]=(z.a[i][j]+a.a[i][k]*b.a[k][j])%MOD;
    return z;
}

矩阵乘法在运算时要注意以下几个基本性质

1.结合性 ( AB) C= A( BC).
2.对加法的分配性 ( A+ B) C= AC+ BC, C( A+ B)= CA+ CB .
3.对数乘的结合性 k( AB)=( kA) B = A( kB).
4.关于转置 (AB)’=B’A’.

所以矩阵乘法好像不支持交换律,这个要注意啊

其实矩阵乘法很简单,只是对应乘一下
真正难点在于如何建出这个矩阵
这个嘛要看具体题目了
比如下面一道例题:


Luogu1962 斐波那契数列
https://www.luogu.org/problem/show?pid=1962
题目要求 f(n) mod 1000000007 的值
我们总不可能一直这么一个一个推下去吧。。。
如果我们构造这样一个矩阵
这里写图片描述
通过斐波那契和矩乘性质,我们可以构造出这样一个矩阵式子
这里写图片描述
对吧,自己推一下就能知道的吧
所以我们就可以放心地求出第n项啦,时间O(log n)

#include
#define ll long long 
using namespace std;
const ll MOD=1000000007;
struct juzhen{
    ll a[3][3];
}x,y,z;
inline juzhen cheng(juzhen a,juzhen b){
    memset(z.a,0,sizeof z.a);
    for(ll i=1;i<=2;i++)
        for(ll j=1;j<=2;j++)
            for(ll k=1;k<=2;k++)z.a[i][j]=(z.a[i][j]+a.a[i][k]*b.a[k][j])%MOD;
    return z;
}
inline ll mi(ll n){
    x.a[1][1]=x.a[1][2]=x.a[2][1]=y.a[1][1]=y.a[1][2]=y.a[2][1]=1;
    while(n!=0){
        if(n&1==1)x=cheng(x,y);
        y=cheng(y,y);n=n>>1;
    }
    return x.a[2][2]%MOD;
}

int main()
{
    ll n;scanf("%lld",&n);
    printf("%lld",mi(n));
    return 0;
}

更多矩乘题目我会更新的啦
敬请期待

你可能感兴趣的:(矩阵乘法,数论/数学,算法笔记)