其他分享
首页 > 其他分享> > 矩陣乘法

矩陣乘法

作者:互联网

以前学过的,现在忘了 居然没有做过笔记

又得再学一遍2333

## 定义

与数学上矩阵乘法相同

如下 \(A\)是一个 \(n*m\)的矩阵
\[ A=\left[ \begin{matrix} a_{1,1} & a_{1,2} & a_{1,3}&...a_{1,m} \\ a_{2,1} & a_{2,2} & a_{2,3}&...a_{2,m} \\ ...& ...&...&...\\ a_{n,1} & a_{n,2} & a_{n,3}&...a_{n,m} \end{matrix} \right] \]

如下 \(B\)是一个 \(m*p\)的矩阵

\[ B=\left[ \begin{matrix} b_{1,1} & b_{1,2} & b_{1,3}&...b_{1,p} \\ b_{2,1} & b_{2,2} & b_{2,3}&...b_{2,p} \\ ...& ...&...&...\\ b_{m,1} & b_{m,2} & b_{m,3}&...b_{m,p} \end{matrix} \right] \]

如下 \(C=A*B (n*p)\)

\[ C=\left[ \begin{matrix} \displaystyle\sum_{i=1}^{m}a_{1,i}*b_{i,1}& c_{1,2} & c_{1,3}&...c_{1,p} \\ c_{2,1} & c_{2,2} & c_{2,3}&...c_{2,p} \\ ...& ...&...&...\\ c_{m,1} & c_{m,2} & c_{m,3}&...c_{m,p} \end{matrix} \right] \]

可知

\[c_{i,j} = \displaystyle\sum_{k=1}^{m}a_{i,k}*b_{k,j}\]

实现

struct matrix
{
    ll n,m,c[MAXN][MAXN];
    matrix operator *(matrix &B) const
    {
        matrix C;
        C.n = n,C.m = B.m;
        for(reg i = 1;i <= n;i++)
            for(reg k = 1;k <= B.m;k++)
            {
                C.c[i][k] = 0;
                for(reg j = 1;j <= m;j++)
                        C.c[i][k] = (C.c[i][k] + c[i][j] * B.c[j][k]) % mod;    
            }
        return C;
    }
    void pr()
    {
        for(reg i = 1;i <= n;i++)
        {
            for(reg j = 1;j <= m;j++)
            {
                printf("%d ",c[i][j]);
            }
            putchar('\n');
        }
        putchar('\n');
    }
};

用途

加快\(dp\)

例如 P1962 斐波那契数列

动态规划方程为

dp[i] = dp[i - 1] + dp[i - 2]

求 第\(n\)项

先画个矩阵
\[ \left[ \begin{matrix} 0&1\\ 1&1\\ \end{matrix} \right] \]

\[ \left[ \begin{matrix} dp[i]&dp[i + 1]\\ \end{matrix} \right] \]

\(\displaystyle\Rightarrow^{A*B}\)

\[ \left[ \begin{matrix} dp[i+1]&d[i+2]\\ \end{matrix} \right] \]

看到这里 就明白了了

但是这样 时间并没有减少啊

\(Attention\)

矩阵乘法满足交换律
\[A*B*C=A*(B*C)\]

那么

\[ \left[ \begin{matrix} 0&1\\ 1&1\\ \end{matrix} \right] \]

可以使用矩阵快速幂了!!

构建 一个矩阵\(B\)

\(S.T.A*B=A\)

在这道题中

\[B=\left[ \begin{matrix} 1&0\\ 0&1\\ \end{matrix} \right] \]

inline matrix qkpow(matrix A,ll n)
{
    matrix res;
    res.n = res.m = 2,res.c[1][1] = res.c[2][2] = 1;
    res.c[1][2] = res.c[2][1] = 0;
    while(n)
    {
        if(n & 1) res = res * A;
        n >>= 1;
        A = A * A;
    }
    return res;
}

\(Code\)

#include <cmath>
#include <cstdio>
#include <climits>
#include <iostream>
#include <algorithm>
using namespace std;
#define isdigit(x) ('0' <= (x)&&(x) <= '9')
#define reg register int
template<typename T>
inline T Read(T Type)
{
    T x = 0;
    bool f = 0;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = 1;a = getchar();}
    while(isdigit(a)) x = (x << 1) + (x << 3) + a - '0',a = getchar();
    if(f) x *= -1;
    return x;
}
typedef long long ll;
const int MAXN = 100,mod = 1000000007;
struct matrix
{
    ll n,m,c[MAXN][MAXN];
    matrix operator *(matrix &B) const
    {
        matrix C;
        C.n = n,C.m = B.m;
        for(reg i = 1;i <= n;i++)
            for(reg k = 1;k <= B.m;k++)
            {
                C.c[i][k] = 0;
                for(reg j = 1;j <= m;j++)
                        C.c[i][k] = (C.c[i][k] + c[i][j] * B.c[j][k]) % mod;    
            }
        return C;
    }
    void pr()
    {
        for(reg i = 1;i <= n;i++)
        {
            for(reg j = 1;j <= m;j++)
            {
                printf("%d ",c[i][j]);
            }
            putchar('\n');
        }
        putchar('\n');
    }
};
inline matrix qkpow(matrix A,ll n)
{
    matrix res;
    res.n = res.m = 2,res.c[1][1] = res.c[2][2] = 1;
    res.c[1][2] = res.c[2][1] = 0;
    while(n)
    {
        if(n & 1) res = res * A;
        n >>= 1;
        A = A * A;
    }
    return res;
}
int main()
{
    ll n = Read(1ll); n -= 1;
    matrix A,B;
    A.n = 1,A.m = 2,A.c[1][1] = A.c[1][2] = 1;
    B.n = B.m = 2,B.c[1][1] = 0,B.c[1][2] = B.c[2][1] = B.c[2][2] = 1;
    matrix C = qkpow(B,n);
    A = A * C;
    printf("%lld",A.c[1][1]);
    return 0;
}

标签:right,&...,matrix,res,end,矩陣,乘法,left
来源: https://www.cnblogs.com/resftlmuttmotw/p/11747193.html