感謝 \(\text{tidongCrazy}\) 傾情授課。
基本形式
把遞推需要用到的項全部存進矩陣裏面,固定的係數則放在轉移矩陣裏面。最後的那個\(g\),其實可以認爲是另外一個(或者多個)遞推數列,它涉及了\(f\)的轉移,於是一起放在矩陣裏面,並且它也實時轉移更新着。
比如轉移項裏面可以有\(3^n\),\(n\)。\(3^n\)到\(3^{n+1}\)的轉移只需要帶個係數\(3\),而\(n\)到\(n+1\)的轉移,我們需要多帶一列\(1\)。
基礎習題
最簡單的一維多階遞推。
P1962 斐波那契數列(例題)
P4838 P哥破解密碼(矩陣加速)
稍微up
P1397 [NOI2013] 矩陣遊戲(矩陣加速)
處理每一行遞推到最後的矩陣,加一個從這一行末尾遞推到下一行第一個位置的矩陣,對這個組合快速冪。
P3216 [HNOI2011]數學作業(矩陣加速)
發現這個\(T(i)\)不好處理,看看\(n\)才\(10^{18}\),直接跑\(18\)個不同的矩陣。
圖論\(\times\)矩陣
大致做法是這樣的。在一個圖裏面跑,題目涉及的路徑長度非常大的時候適用。
由\(t-1\)階的答案擴展到\(t\)階的答案,需要多擴展一條邊。設\(f^t_{i,j}\)表示\(i->j\),走\(t\)步的方案數。則
跟矩乘的形式相符,可以以\(1\)階矩陣爲轉移矩陣爆加速。
另一個理解則是,這個\(1\)階的\(01\)矩陣是該圖的鄰接矩陣,當\(k->j\)有連邊時,就能爲\(f^{t}_{i,j}\)貢獻\(f^{t-1}_{i,k}\)的方案數。
P2233 [HNOI2002]公交車路線(圖論與矩陣結合)
P2151 [SDOI2009] HH去散步(有限制的路徑計數)
這個限制的做法是,把一條邊拆成兩個點(表示雙向的邊)。做完了(
P4159 [SCOI2009] 迷路(圖論中鄰接矩陣的巧妙轉化)
這個邊權最多隻有\(9\),那我們存儲相鄰\(9\)階的信息到一個矩陣裏。
...........等一下,這樣能做麼...
題解給的方法是把一條邊暴拆成雙向各九個,沒了(
分組矩陣
矩陣變化的週期很小,把週期內的每個矩陣處理出來,合在一起快速冪就行了。
P2579 [ZJOI2005]沼澤鱷魚(分組矩陣優化)
P3821 Isaac(分組矩陣優化)
相比上一題加個二分就好啦。
矩陣乘法變形
P5678 [GZOI2017]河神(矩陣乘法變形)
這倆運算符性質很好,看看下面矩陣乘法結合律的證明吧。
注意與運算的單位是\(111111111\)(
CF576D Flights for Regular Customers(矩陣乘法優化)
按\(d_i\)排序,每次跑到下一個\(d_i\)就加邊改矩陣。
由於只需要可行性,可以改成\(01\),位運算,然後bitset壓一下。
怎麼還有題需要bitset卡個64的
P6569 [NOI Online #3 提高組] 魔法值(矩陣乘法變形+優化)
關於矩陣乘法結合律的證明(sun123zxy)
與和或運算顯然是滿足的。
然後就是這題奇怪的優化,像我這種從來把\(log\)當作不存在的人就已經寄了。
光速冪
雜記
還可以做類似一個結構體內,一些變量相互加減之類變化的運算。
D - Binary Representations and Queries
第一步結論我甚至暫時不會證。
後一步則是讓兩個元素一一對應的集合(其實就是一對一對的),每次讓一邊元素加上另一邊與之對應元素的值。
這個只是矩陣乘法,而不是矩陣加速(
P7453 [THUSCH2017] 大魔法師
又想提一嘴矩陣的運算律,我一直沒搞得比較清楚。
矩陣運算律
矩陣線性運算
(1) 矩陣加法
交換律:\(A+B=B+A\)
結合律:\((A+B)+C=A+(B+C)\)
(2) 矩陣數乘
結合律:\(\lambda\mu A=\lambda(\mu A)\)
分配率 \(1\):\(\lambda(A+B)=\lambda A+\lambda B\)
分配率 \(2\):\((\lambda+\mu)A=\lambda A+\mu A\)
矩陣乘法
結合律 \(1\):\((AB)C=A(BC)\)
結合律 \(2\):\(\lambda (AB)=(\lambda A)B=A(\lambda B)\)
分配率:\(A(B+C)=AB+AC\),\((B+C)A=BA+CA\)
這題是在線段樹上做區間乘矩陣,區間覆蓋,區間加,區間乘。後三個運算分別對矩陣不同對象。
滿足了上述一系列優秀的性質,來考慮怎麼打 \(tag\)。
迴歸最一般的線段樹區間乘與區間加。
比如標記 該節點需要先 \(\times a\) 再 \(+b\),子節點已有的標記是需要先 \(\times c\) 再 \(+d\),那麼子節點:
那麼子節點的 \(c\) 就該變成 \(c\times a\), \(d\) 變成 \(d\times a+b\)。
類比標記打法:該節點需要 \(\times P\) 後分別 $\times v\ ,+k\ ,\ $覆蓋
一種方法是拆成乘與加矩陣(\(3\times 3\) 矩陣),另一種是全部拆成乘矩陣。後者(\(4\times 4\) 矩陣,加了一列常數項)應該是好寫很多的,但不知道會不會複雜度爆炸(
哦我草,\(5s\) 啊,那沒事了,我傻逼了,比上面那個還好寫(?)