题解 P2222 【[HNOI2001]矩阵乘积】

囧仙

2020-06-06 22:22:38

Solution

想到了这道题的两个解法,来发一下题解 我们假设所有矩阵都是 $n \times n$ 的,因为就算不是我们也可以通过补 $0$ 变为 $n \times n$ - **稀疏矩阵快速乘法** 稀疏矩阵的定义题目中已经给出了,也就是只有 $m$ 个点有值,剩余点都是 $0$ 的矩阵($m$ 与 $n$ 同阶) 那么考虑计算 $A \times B = C$,$C_{i,j} = \sum\limits_{k = 1}^n A_{i,k} \times B_{k,j} $ 显然只有 $A_{i,k},B_{k,j}$ 都有值的时候,计算它才是有必要的,否则贡献为 $0$ 所以现在就是要想办法去除无用计算 考虑对第 $i$ 行开一个 `vector`,记录这一行那些位置有值,值都是多少 对第 $j$ 行也是类似操作,记录这一列那些位置有值,值都是多少 然后我们用类似归并的顺序来计算 $C_{i,j}$ 分析一下复杂度,$A$ 的第 $i$ 行在乘法过程中会被用 $n$ 次,$B$ 的第 $j$ 列在乘法过程中也会被用 $n$ 次 所以复杂度就是:$\sum\limits_{i = 1} ^ n cA_i \times n + \sum\limits_{j = 1} ^ n cB_j \times n$ $cA_i$ 表示 $A$ 矩阵第 $i$ 行有值的数量,$cB_j$ 表示 $B$ 矩阵第 $j$ 列有值的数量 显然 $\sum\limits_{i = 1} ^ n cA_i = m$,$\sum\limits_{j = 1} ^ n cB_j = m$,所以在 $n,m$ 同阶的情况下,我们得到了一个 $n ^ 2$ 矩阵乘法 但缺陷在于,两个稀疏矩阵相乘后,结果很可能不是稀疏矩阵了 - **单点求矩阵乘法结果** 当我们在两个矩阵相乘的结果上,只求一个点的点值的话,那么显然不需要求出所有点值 实际上,如果我们要求 $(x,y)$ 的值的话,只需要将 $A$ 矩阵的第 $x$ 行与 $B$ 矩阵的第 $y$ 列相乘就可以了 进一步得,我们实际上只需要知道 $A$ 矩阵的第 $x$ 行和 $B$ 矩阵的第 $y$ 列就可以了 上面这句话是什么意思呢?看下一段你就知道了~ - **本题的加强版** 就是在本题的题意下,把 $3$ 个矩阵相乘,改为 $8$ 个矩阵相乘,数据范围不变(当然时限、空限可能得略微开大) 显然这样你直接套上面两个做法都不行了,需要结合起来 设 $8$ 个矩阵分别为 $A_0,A_1,A_2,A_3,A_4,A_5,A_6,A_7$,结果为 $D$ 那么 $D = A_0 \times A_1 \times A_2 \times A_3 \times A_4 \times A_5 \times A_6 \times A_7$ 根据矩阵结合律,得到 $$D = ((A_0 \times A_1) \times (A_2 \times A_3)) \times ((A_4 \times A_5) \times (A_6 \times A_7))$$ $A_0 \times A_1$,$A_2 \times A_3$,$A_4 \times A_5$,$A_6 \times A_7$,都是两个稀疏矩阵相乘,可以直接 $n ^ 2$ 得出答案,我们设结果为 $B_0,B_1,B_2,B_3$ $D = (B_0 \times B_1) \times (B_2 \times B_3)$ 再次设 $B_0 \times B_1 = C_0,B_2 \times B_3 = C_1$ 因为我们要求 $D_{x,y}$,所以我们只需要知道 $C_0$ 的第 $x$ 行和 $C_1$ 的第 $y$ 列就可以了 而 $C_0$ 的第 $x$ 行,$C_1$ 的第 $y$ 列,朴素计算就是 $n ^ 2$ 的 最后把它们 $O(n)$ 地乘起来,就得到答案了 总复杂度还是 $O(n ^ 2)$ 的,非常的优秀 再多我就不会了,但是感觉这个 $8$ 矩阵相乘也挺好了 - **本题题解** 蛤?$8$ 矩阵相乘你会了,$3$ 矩阵相乘你不会? ~~但是因为这题读入太迷惑了,所以我没有去写过~~ 读入的话可以去看隔壁的题解,这里就不讲啦