題目
傳送門 to luogu
思路
動態規劃
不難想到這樣的 dp :用 f(x,k) 表示走到第 x 個點,當前字符串狀態是 Trie 樹上的 k ,最小代價。
然後就 T 飛了。
發現 f 的定義有很多是無效的。因爲到達 x 的邊只有那麼多條,在 x 點上的時候,只可能是那些狀態。
於是更改定義,用 f(x) 表示 最後一步走的是第 x 條邊,最小代價是多少。
此時就只有 O(m) 的狀態數量了。
轉移就套一個 dijkstra 即可。時間複雜度 O(mlogm) ……嗎?
注意到狀態轉移可能發生 O(m2) 次。完了。真是糟糕!
優化建邊
狀態轉移的本質是邊的數量,所以我們得換一個方法。
在虛樹
的相關內容中,我們已經講過了,k 個點及其 lca 的數量是 O(k) 的。
而 Trie 樹上兩個點的 lcp 恰好爲 depth(lca) 。
所以,對於某一個點 x ,我們將與其相連的邊上的字符串提出來。這樣一來,就有了 deg(x) 個字符串。
我現在想知道這 deg(x) 個字符串,兩兩的 lcp 。——這不就是 deg(x) 個點,兩兩求 lca 嗎?
所以我們將其按照 dfs 序排序(就如我們處理虛樹那樣),不妨設其爲 v1,v2,v3,…,vz(z=deg(x)) ,那麼一定有(對於 1≤a<b≤z )
lcp(va,vb)=i=aminb−1lcp(vi,vi+1)
求 min 恰好與求最短路掛鉤。我們是不是有一種獨特的構建方法呢?
對於每條入邊,將其向 dfs 序比自己大的入邊連邊。這樣的邊太多,所以只連接 dfs 序最小的一個。出邊同。權值統一設置爲 0 。
對於每個 a∈[1,z) ,求一對 l,r ,滿足 l 爲入邊、r 爲出邊,並且 l≤a<r 。找到 l 最大、r 最小的一對,將 l,r 之間連邊,權值爲 lcp(va,va+1) 。
放一張圖,形象的理解這一建邊:
本質是考慮 lcp(va,va+1) 會被哪些 lcp 使用到。權值爲 0 的那些邊,也就是這個用處。
一些坑點
剛纔只考慮了 dfs 序較小者走到 dfs 序較大者的邊,所以我們反過來再做一次即可。
但是不能在原有的基礎上直接加入這些邊,所以每個點需要分裂成四個點。
代碼
咕咕咕……
聽思路都覺得很長很難打對吧?
我試着去打了,但是我失敗了。