最佳化半群結構的線段樹資訊維護

Shunpower發表於2024-08-29

今天在做區間歷史和。感覺給每個標記一個含義實在太抽象了,遂聽從白神建議學習矩陣維護資訊和最佳化半群結構。

前置知識:大魔法師,用矩陣維護輪換資訊。我們發現區間歷史和事實上是對“歷史和”變數被“和”變數輪換加法的結果,不知道為什麼以前沒反應過來和大魔法師有關。

區間加和區間歷史和

用這個來進行舉例。

我們考慮我們做區間加和區間歷史和需要的資訊。不難想到應該有三個:\(sum\) 表示區間現在的和,\(l\) 表示區間的長度,\(hsum\) 表示區間歷史和。把它寫成矩陣(或者說列向量)形如:\(\begin{bmatrix}sum \\l \\ hsum\end{bmatrix}\)

考慮區間加操作,使用一些構造能力構造懶標記即可,很容易得到:

\[\begin{bmatrix} 1 & v & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{bmatrix} \times \begin{bmatrix} sum \\ l \\ hsum \end{bmatrix} = \begin{bmatrix} sum+lv \\ l \\ hsum \end{bmatrix} \]

這樣就維護好了。注意我們把列向量的資訊放到右邊,這樣每次新資訊都可以利用舊資訊的每一項轉移。

那麼也容易構造重新整理歷史和:

\[\begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 1 & 0 & 1 \end{bmatrix} \times \begin{bmatrix} sum \\ l \\ hsum \end{bmatrix} = \begin{bmatrix} sum \\ l \\ hsum+sum \end{bmatrix} \]

直接用大魔法師一樣的辦法用矩陣乘法合併懶標記就行。注意新來的標記往舊標記的前面乘才是正確順序。

但是這樣太慢了。

我們發現矩陣裡面有很多位置是沒用的。我們可以透過刻畫標記合併的式子來觀察哪些位置是會變化的,哪些位置會是定值。比如我們發現:

\[\begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ 1 & 0 & 1 \end{bmatrix} \times \begin{bmatrix} 1 & v & 0\\ 0 & 1 & 0\\ 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} 1 & v & 0\\ 0 & 1 & 0\\ 1 & v & 1 \end{bmatrix} \]

我們發現只有三個位置 \(A_{01},A_{20},A_{21}\) 在三個矩陣中是不一樣的。其他位置都一模一樣。我們把這三個位置在兩個矩陣裡都用字母替掉可以發現乘出來的矩陣也只有這三個位置會有變化,那麼無論怎麼乘下去都是這三個位置。

換而言之,一個矩陣的確定只需要這三個元素就夠了。所以我們考慮最佳化半群結構,我們只需要設計一個和矩陣等價的運算可以維護這三個值的變化即可。我們把這三個值放回轉移裡面發現:

\[\begin{bmatrix} 1 & a & 0\\ 0 & 1 & 0\\ b & c & 1 \end{bmatrix} \times \begin{bmatrix} 1 & a' & 0\\ 0 & 1 & 0\\ b' & c' & 1 \end{bmatrix} = \begin{bmatrix} 1 & a'+a & 0\\ 0 & 1 & 0\\ b'+b & a'b+c+c' & 1 \end{bmatrix} \]

所以我們直接維護 \(\text{tag}=\{a,b,c\}\) 即可。注意新的運算仍然不存在交換律,打標記時需要左乘。

考慮寫出矩陣和資訊(那個列向量)的乘法來確定標記和資訊乘在一起的形態。

相關文章