矩阵快速幂——从入门到放弃(看这一篇就够了)

Part 1: 矩阵的运算

矩阵有许多种运算,这里列举出其中最常用的三个。为了方便书写,假设参与运算的两个矩阵是 A , B A, B A,B,表示运算结果的矩阵是 C C C

①矩阵加法。对于两个大小相同的矩阵,我们可以相加。

其中 C i , j = A i , j + B i , j C_{i,j}=A_{i,j}+B_{i,j} Ci,j=Ai,j+Bi,j

②矩阵减法。对于两个大小相同的矩阵,我们可以相减。

其中 C i , j = A i , j − B i , j C_{i,j}=A_{i,j}-B_{i,j} Ci,j=Ai,jBi,j

③矩阵乘法。只要 A A A的列数等于 B B B的行数就可以相乘。

其中 C i , j = ∑ i = 1 m A i , k B k , j C_{i,j}=\sum_{i=1}^m A_{i,k}B_{k,j} Ci,j=i=1mAi,kBk,j

换句话说, C i , j C_{i,j} Ci,j表示对于 A A A的第 i i i行, B B B的第 j j j列组成的两个长度相等的序列,对应位置相乘的值之和。

可以发现,矩阵乘法是有结合律与分配率的,但绝对没有交换律

现在,可以说我们学会了许多种矩阵运算。现在,我们通过 4 4 4道例题与许多练习题,对矩阵加深理解。

Part 2: 例题与讲解

例1. 斐波那契数列

Description

求斐波那契数列的第 n n n项的值。由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

n < 2 63 n<2^{63} n263

Solution

显然,我们不能采用 O ( n ) O(n) O(n)的线性递推解法。

那我们怎么办呢?先把递推的式子给写下来:

f i = f i − 1 + f i − 2 f_i=f_{i-1}+f_{i-2} fi=fi1+fi2

现在,我们开始考虑用矩阵乘法来优化。即,我们考虑,如何从 [ F k , F k − 1 ] [F_k, F_{k-1}] [Fk,Fk1]推到 [ F k + 1 , F k ] [F_{k+1},F_k] [Fk+1,Fk]

显然, F k + 1 = F k + F k − 1 , F k = F k F_{k+1}=F_{k}+F_{k-1}, F_k=F_k Fk+1=Fk+Fk1,Fk=Fk。所以,我们可以得到一个式子:

[ F k , F k − 1 ] × [ 1 1 1 0 ] = [ F k + 1 , F k ] [F_k,F_{k-1}]×[\begin{matrix}1 & 1 \\1 & 0\end{matrix}]=[F_{k+1}, F_k] [Fk,Fk1]×[1110]=[Fk+1,Fk]

这个式子显然是正确的,可以结合第一部分中的矩阵乘法的定义与 F k + 1 = F k + F k − 1 , F k = F k F_{k+1}=F_{k}+F_{k-1}, F_k=F_k Fk+1=Fk+Fk1,Fk=Fk来证明。读者可以自己推一下。

简记 M M M表示矩阵 [ 1 1 1 0 ] [\begin{matrix}1 & 1 \\1 & 0\end{matrix}] [1110],那么答案就是 M n − 1 M^{n-1} Mn1

由于矩阵乘法存在结合律,所以我们可以使用矩阵快速幂来优化这个乘法。

时间复杂度 O ( 2 3 l o g n ) O(2^3 logn) O(23logn)

Summary

请各位读者总结一下三个问题:

①我们是如何构造矩阵的?

②矩阵快速幂起到了怎么样的效果?

③什么样的题目可以用矩阵快速幂来优化?

练1. P2359三素素数(数据加强: n ≤ 1 0 18 n≤10^{18} n1018)

练2. P5343[XR-1]分块

练3. P1939[模板]矩阵加速

例2. [SCOI2009]迷路

Description

给定一个 n n n个点, m m m条边的有向图,每条边都有一个长度。求有多少种路径,使得从 1 1 1号节点到 n n n号节点走过的长度为 t t t

由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

n ≤ 10 , t ≤ 1 0 18 n≤10, t≤10^{18} n10,t1018

Solution

请确保您已经 A C AC AC前面的练 1 , 2 , 3 1,2,3 1,2,3

首先,假设所有边权都是 1 1 1,那么本题做法就十分显然了:直接将图转化为一个邻接矩阵(GA),然后答案就是该矩阵 t t t次方的第 1 1 1行第 n n n列。

但是如果边权不一定全是 1 1 1呢?那我们就把边权变成 1 1 1呗。即,我们拆点,假设存在一个点 a a a,那么我们新建节点 b , c , d … … b,c,d…… b,c,d,使得 b b b a a a有一条长度为 1 1 1的有向边, c c c b b b也有一条长度为 1 1 1的有向边……

对于一条连接 u , v u,v u,v的边权为 w w w,我们只需要从 u u u到离 v v v距离为 w − 1 w-1 w1的点连一条边权为 1 1 1的边。

此时,点数为 10 n 10n 10n,我们直接对它做矩阵快速幂即可通过本题。

时间复杂度 O ( l o g t ( 10 n ) 3 ) O(logt(10n)^3) O(logt(10n)3)

Summary

本题使用矩阵快速幂优化法宝1——拆点来把整个邻接矩阵转化为了一个 01 01 01的矩阵,然后使用快速幂优化了本题。

同时,我们可以总结一下:我们是如何想到用矩阵快速幂去优化的?

事实上,很简单:看数据范围。如果数据中存在某个值特别小,往往是:

①让我们枚举它的状态;
②让我们使用状压 d p dp dp
③让我们构造一个长宽为该值的矩阵,并用该矩阵来优化 d p dp dp

事实上,许多矩阵快速幂的题目与图论有所结合。

例3. [NOI Online #3提高组]魔法值

Description

给定一个 n n n个节点, m m m条边的无向图。每次所有节点都会同时变为所有与其相连的节点的权值的异或和。求变换 t t t次之后, 1 1 1号节点的权值。多次询问

由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

n , q n, q n,q(询问次数) ≤ 100 ≤100 100, t ≤ 2 62 t≤2^{62} t262

Soluion

首先,我们通过无向图构造矩阵,对于每次询问直接做矩阵快速幂,时间复杂度为 O ( q n 3 l o g f i ) O(qn^3log{f_i}) O(qn3logfi)。期望得分 40 40 40分。

我们考虑如何将其优化为 O ( q n 2 l o g f i ) O(qn^2log{f_i}) O(qn2logfi)。即,我们将 f i f_i fi进行二进制拆分,倍增预处理;查询的时候,用 1 × n 1×n 1×n的矩阵乘上对应的二进制位即可。

时间复杂度 O ( l o g f i n 3 + q n 2 l o g f i ) O(log{f_i}n^3+qn^2log{f_i}) O(logfin3+qn2logfi),可以通过本题。

Summary

对于这一类多次询问的问题,我们可以使用倍增预处理+向量乘矩阵来优化。

练4 [NOI2020D1T1]美食家

提示: 分段转移,拆点+向量乘矩阵优化,略微卡常。

例4. [TJOI2017]可乐

Description

给定一个 n n n个节点, m m m条边的无向图,一只可爱的机器人从 1 1 1号节点出发,每次可以选择呆在原地,去一个相邻点或者自爆。求机器人在 t t t秒内的行为方案数。

由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

n ≤ 30 , t ≤ 1 0 6 n≤30, t≤10^6 n30,t106

Solution

我们唯一要做的,就是考虑如何维护"呆在原地"与"自爆"的情况。添加的每种情况,我们都尝试转化为添加一条边或一个点。

①呆在原地: 对于每个节点,有一个自环;

②自爆: 构造节点 0 0 0,其他节点可以过去,但它不能到别的节点。这里的 0 0 0号节点象征着"自爆"。

于是,我们加了一些边与 0 0 0号节点,现在题目就不存在呆在原地与自爆的情况了。

时间复杂度 O ( n 3 l o g t ) O(n^3 log t) O(n3logt)

Summary

有时候,对于一些限制,我们可以通过一些耍巧的方式来添加一些边与节点,然后就把题目大大地简化了。

例5. 旅行

Description

珂朵莉要去旅行啦!

她旅行的地方是一个 n n n个节点, m m m条边的有向图,走每条边都花费 1 1 1个时间单位,且她从 1 1 1号节点出发。定义 f x , y , t f_{x,y,t} fx,y,t表示珂朵莉从 x x x走到 y y y且总共花费 t t t的时间单位的方案数。

q q q次询问,每次询问给定 x , y , l , r x,y,l,r x,y,l,r,需要你求出 ∑ i = l r f x , y , i \sum_{i=l}^r f_{x,y,i} i=lrfx,y,i的值。

由于答案可能过大,请将其对 1 0 9 + 7 10^9+7 109+7取模。

q , n ≤ 50 , l , r ≤ 1 0 18 , r − l ≤ 100 q, n≤50, l, r≤10^{18}, r-l≤100 q,n50,l,r1018,rl100

Solution

如果我们枚举 i i i,对于不同的 i i i分别做一次矩阵快速幂,那么时间复杂度会爆炸。

不用慌,我们写下式子: ∑ i = l r M i \sum_{i=l}^r M^i i=lrMi

其中 M M M表示我们构造的矩阵。

观察一下这个式子,我们可以通过矩阵的分配率来把它变一下: M l − 1 ∑ i = 1 r − l + 1 M i M^{l-1} \sum_{i=1}^{r-l+1} M^i Ml1i=1rl+1Mi

由于 r − l ≤ 100 r-l≤100 rl100,所以我们可以预处理出 M 1 , M 2 , M 3 … … M 101 M^1, M^2, M^3……M^{101} M1,M2,M3M101并维护这个矩阵的前缀;对于询问我们只需要求出 M l − 1 M^{l-1} Ml1,然后将 M l − 1 M^{l-1} Ml1乘上 ∑ i = 1 r − l + 1 M i \sum_{i=1}^{r-l+1} M^i i=1rl+1Mi即可。

时间复杂度 O ( 100 n 3 + q ( l o g t + n 3 ) ) O(100 n^3+q(logt+n^3)) O(100n3+q(logt+n3)),可以通过本题。

Summary

刚开头我们介绍了矩阵乘法与矩阵加法,主要就用在了分配率上。

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/108922884