FarmerJohn

某OIer

{算法}YY矩阵乘法

矩阵乘法在OI历程中占据了极其重要的地位
而且也很好用~~

矩阵乘法的定义

我们定义A[x,y]B[y,z]=C[x,z]

Ci,j=k=1yAi,kBk,j

非常简单,可以看出朴素相乘的复杂度是O(xyz)
//然而,暂时我还不了解更简单的办法

二进制矩阵

呃,简单地说,就是将乘法换成and(与运算),加法换成xor(异或)

矩阵乘法的性质


  1. 满足结合律即(A∗B)∗C=A∗(B∗C)
  2. 不满足交换律即A∗B∗C≠C∗B∗A,严谨的说,是不一定的。
    通俗的讲,会出现无法进行运算的情况,还怎么交换律?
    (这取决于矩阵乘法的定义)
  3. 由(1)可得,它可以运用快速幂

作为一个蒟蒻,我能做的是给你们这个网址(至少我没有看懂)

矩阵乘法的作用

让我们先来看一道题目

斐波那契数列
 大家都知道斐波那契数列,其中F(1)=0,F(2)=1,F(N)=F(N-1)+F(N-2)(N>=3),输入N(1<=N<=10^9),计算F(N)mod 100000007的值

方法很简单,计算Fn,然后取模

那么问题来了

How can you compute the answer to this question?
简单地套公式显然不会对,我们考虑运用矩阵乘法解决这道题。

我们定义矩阵A[1,2]表示斐波那契数列i1i(取模意义下)
我们的目标是,将矩阵A和其他矩阵相乘,做到每次使i+1(即多推一位)
我们再引用一个矩阵B[2,2],适当构建B,使A*B刚好推后了一位。
怎么构建呢?
还是留给大家想想吧。
然而这还不够,尤其是时间

满足结合律即(A∗B)∗C=A∗(B∗C)可得,它可以运用快速幂
ans=ABBB
ans=ABn

提供Code

const
        moder=100000007;
type
        matrix=array[1..2,1..2] of int64;
var
        n:longint;
        a,b:matrix;
        i,j,l:longint;
function matr(a,b:matrix):matrix;//表示A*B
var
        c:matrix;
        i,j,l:longint;
begin
        for i:=1 to 2 do
        for j:=1 to 2 do
        begin
                c[i,j]:=0;
                for l:=1 to 2 do
                        c[i,j]:=(c[i,j]+(a[i,l]*b[l,j]))mod moder;
        end;
        exit(c);
end;
function qsm(x:matrix;y:longint):matrix;//快速幂(矩阵版)
var
        c:matrix;
begin
        if y=1 then exit(x);
        if y=0 then
        begin
                c[1,1]:=1;c[1,2]:=0;
                c[2,1]:=0;c[2,2]:=1;
                //此处c相当于1
                exit(c);
        end;
        if(y shr 1=0)then
                exit(qsm(x,y and 1))
        else
        if(y shr 1=1)and(y and 1=0)then
                exit(matr(x,x))
        else
        if(y shr 1=1)then
                exit(matr(qsm(x,2),qsm(x,y and 1)))
        else
        if(y and 1=0)then
                exit(qsm(qsm(x,y shr 1),2))
        else
                exit(matr(qsm(qsm(x,y shr 1),2),qsm(x,y and 1)));
end;
begin
        b[1,1]:=0;b[1,2]:=1;
        b[2,1]:=1;b[2,2]:=1;
        readln(n);
        a:=qsm(b,n-2);
        writeln(a[2,2]);
        close(input);close(output);
end.
阅读更多
版权声明:本文为博主原创文章,转载时请标明出处。 https://blog.csdn.net/FarmerJohnOfZS/article/details/51558589
文章标签: 算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

{算法}YY矩阵乘法

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭