1. 程式人生 > >【洛谷P1939】【模板】矩陣加速(數列)

【洛谷P1939】【模板】矩陣加速(數列)

題目大意:

題目連結:https://www.luogu.org/problemnew/show/P1939
f 1 = f 2 =

f 3 = 1 , f n = f
n 3
+ f n 1
f_1=f_2=f_3=1,f_n=f_{n-3}+f_{n-1} 。求 f n f_n


前言

這篇部落格並不是專門來介紹矩陣乘法加速遞推的。
但是既然是模板題就提一下吧。


什麼是矩陣乘法?

下面是來自度孃的解釋:
在這裡插入圖片描述

在這裡插入圖片描述
也就是說,對於兩個矩陣 A A B B ,在滿足第一個矩陣的列數=第二個矩陣的行數時,這兩個矩陣就可以相乘。那麼假設 A A m × p m\times p 的矩陣, B B p × n p\times n 的矩陣,那麼他們相乘得到的矩陣 C C 就是一個 m × n m\times n 的矩陣。
而且對於矩陣 C C 的任意元素 i j _{ij} ,都等於矩陣A第i行的所有數字分別乘上矩陣B第j列的所有數字之和。(其實就是上圖的公式)


矩陣乘法和遞推的關係?

矩陣乘法和遞推關係最密切的例子就是斐波那契數列了。↓
矩陣乘法求斐波那契數列
現在看不懂沒關係,可以慢慢理解。
我們知道,斐波那契數列有這樣的定義:
f i = f i 1 + f i 2 f_i=f_{i-1}+f_{i-2}
那麼如果我們有一個 2 × 2 2\times 2 的矩陣,其中第一行分別是 f i 1 f_{i-1} f i 2 f_{i-2} 。我們的目標是把第一行承上一個矩陣變成 f i f_i f i 1 f_{i-1} 。那麼應該怎麼辦呢?
在這裡插入圖片描述

首先,矩陣 A A 和矩陣 C C 都含有 f i 1 f_{i-1} 這一項。那麼就先從這裡下手。
我們知道,矩陣 C C f i 1 f_{i-1} 在第 1 1 行第 2 2 列。那麼,根據公式,可以得到
C 1 , 2 = A 1 , 1 × B 2 , 1 + A 1 , 2 × B 2 , 2 C_{1,2}=A_{1,1}\times B_{2,1}+A_{1,2}\times B_{2,2}
也就是說
f i 1 = f i 1 × B 2 , 1 + f i 2 × B 2 , 2 f_{i-1}=f_{i-1}\times B_{2,1} +f_{i-2}\times B_{2,2}
那麼很明顯,我們可以得到 B 2 , 1 = 1 , B 2 , 2 = 0 B_{2,1}=1,B_{2,2}=0 。這樣可以保證進行矩陣乘法之後 C 1 , 2 C_{1,2} f i 1 f_{i-1}
在這裡插入圖片描述
那麼現在來看矩陣 C C 中的 f i f_i 。我們要保證的是
C 1 , 1 = A 1 , 1 × B 1 , 1 + A 1 , 2 × B 2 , 1 C_{1,1}=A_{1,1}\times B_{1,1}+A_{1,2}\times B_{2,1}
也就是說
f i = f i 1 × B 1 , 1 + f i 2 × B 2 , 1 f_{i}=f_{i-1}\times B_{1,1}+f_{i-2}\times B_{2,1}