最近刷了一下字尾自動機。
題其實做了也不少了,稍微有一點理解。(教練:得理解深刻)
1.我個人認為$parent$樹其實是一顆虛樹(最近又學了虛樹,做了三道題),虛樹的思想是只留存關鍵點以及關鍵點的$lca$。
$parent$樹其實相當於字尾樹的虛樹,只留存了一些關鍵點。可以發現對於同乙個$right$集合來說,在字尾樹上有很多節點的$right$集合是完全相同的,這樣在字尾樹上這些節點其實是一段從上到下的連續的,度為1的節點。$sam$把它們壓在一起,用$min,max$的長度來代表這個節點所包含的集合(對於給定的$right$集合,只要再給出長度就可以確定子串),這樣實現了對字尾樹空間的優化。
2.$trans$轉移邊是相當於在結尾加入字元,$parent$樹邊其實是相當於在開頭加入字元。
3.每個字首節點都會丟失乙個字尾資訊(就是最長字首,因為無法再從前面加字元了)。
4.$len$值代表的是一條從原點經過$trans$邊到達某個節點的最長路徑。
5.$parent$樹上字首節點與其父親的$len$相減就是本質不同子串個數。
題列(全是板子題):
1.弦論
如果是本質不同的話,只需要強制每個節點的$right$集合大小為$1$即可,先$dp$一次求出路徑數(從某個點開始的路徑數等於從這個點代表的字首所包含的子串個數),這樣直接在$trans$上從小到大列舉轉移即可。
如果是本質可以相同的話,求出每個節點的$right$集合大小即可,仍然$dp$一次求出路徑,不過求出的是$right$集合的總和,同樣在$trans$上從小到大列舉轉移即可。
可以發現本質不同和本質相同的區別就是在於$right$集合是否可以算作多次,而從源點到某個點的路徑數就是以這個點的$right$集合為出現位置的子串個數。
2.諸神眷顧的幻想鄉
這個題其實挺簡單的,是廣義字尾自動機,在$trie$樹上的應用。題目給出$trie$樹且僅有$20$個葉子節點,我們直接暴力插入20個$trie$數進入字尾自動機,每到乙個節點就將當前的終止節點記錄下來,從$trie$上回溯的時候將終止節點返回這個點。
這樣建出來之後直接求本質不同子串即可。
廣義字尾自動機就是通過終止節點的變化來實現分離多個串的,理論上也說的通,終止節點代表的是乙個串的可匹配結尾的子串。
3.公共串
板子題了。
對乙個串建字尾自動機,然後讓其他串在自動機上跑,跑到某個節點就記錄一下匹配長度,同時將$parent$樹上的子節點的匹配資訊轉移到父親節點上。
最終將其他串全部都經過的節點的最長長度取$min$,再和這個節點的$len$取$min$即可。
公共串匹配仍然是利用了$right$集合的包含性所代表的子串匹配含義。
4.差異
前兩項可以直接求,求得其實是各個字尾的最長公共字首的長度,首先反轉串,變為各個字首的各個最長公共字尾的長度。
在$parent$樹上所有字首節點互相的$lca$的$len$值的和。直接樹形$dp$即可。
$parent$樹上$lca$及其父鏈的含義其實是兩個字首的公共字尾集合。
5.工藝
叫什麼最小迴圈位移。
文字串複製兩次加入字尾自動機,從源點開始每次跑字典序最小的$trans$邊,跑到長度為$n$就停止即可。
複製兩次就保證了可以以任何乙個位置為起點。
6.生成魔咒
板子題,求本質不同子串。
建字尾自動機之後直接用$parent$所有字首節點父子的$len$值相減就可以得到當前$right$集合含結尾的子串個數,累加起來其實就是本質不同子串(right集合不同的子串)。
7.substring
本來也沒什麼難得。
用$lct$動態維護$parent$樹,然後乙個乙個操作進行$link,cut$同時動態維護子樹$right$集合大小即可。
其實就是資料結構結合字尾自動機的乙個經典應用了。
8.cheat
仍然是板子。
首先可以看出$l_0$的單調性,那麼我們二分答案。
然後首先讓模式串在文字串上面匹配得到每個位置能夠匹配的最長長度。
設位置$i$匹配的最長長度是$mx[i]$
然後考慮用$dp$來$check$二分。
這樣我們設$dp[i]$為串的前$i$個位置匹配的最長長度。
那麼得到轉移:
$$dp[i]=\max\limits_^$$
但是複雜度是$o(n^2)$的,只能得到75分。
可以發現對於每個串來說$i-mx$值都是單調不降的。
那麼我們用單調佇列優化他即可。
最終複雜度$o(nlogn)$
字尾自動機和$dp$結合的經典例子。
9.品酒大會
和差異那道題幾乎一模一樣,只不過要求方案和最值兩個。
同樣的找到每個節點的$lca$並且將之計入$lca$的$len$的方案,這樣對$len$取乙個字尾和,就的到了全部長度的方案。
最值的話因為有負數所以麻煩一些,要記錄最大和最小兩個值,同樣在樹形$dp$的時候求出最值,同樣對所有的$len$取乙個字尾$max$即可。
還是$parent$樹的樹形$dp$的經典應用。
未完。
字尾自動機總結
字尾自動機是一種確定性有限自動機 dfa 它可以且僅可以匹配乙個給定串的任意字尾。字尾自動機的增量演算法 struct sam c else else last np view code 字尾自動機構造完成之後,我們得到了4個東西 轉移dag,parent樹,每個點的right集合,每個點的字串集合...
字尾自動機
基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...
字尾自動機
常用於處理字串問題,可以高效解決許多字串問題。有點像將乙個字串的所有字尾都建在乙個ac自動機上,但不同的是字尾自動機的節點數最多為2 n,因為它只記錄需要記錄的點,一些沒有記錄東西的點可以視為與下面有價值的節點並在一起,這樣大大降低了時間複雜度和空間複雜度。對於每乙個節點記錄它的後面加上每個字元後字...