字尾陣列應用小結
前言
之前學了字尾陣列,這真是一個神奇的東西。早就想總結一些SA的應用,但一直沒時間,現在終於抽出空來寫一下自己的心得。
本文只討論字尾陣列的一些應用,不一定全面,僅供參考
還不會後綴陣列的同學請自學後再看本文,這裡不再贅述字尾陣列的基礎實現
推薦一篇部落格,裡面對於基礎的字尾陣列總結的比較到位,YxuanwKeith大神的五分鐘搞懂字尾陣列!字尾陣列解析以及應用
請不要吐槽標題,不知道你五分鐘搞不搞得懂,反正我搞不懂 = = 。
下面進入正題。
字尾陣列相關應用
單個字串相關問題
比較常見的思路是先構造字尾陣列,然後求Height陣列,用這兩個來求解。
重複子串問題
可重疊的最長重複子串問題
因為可重複,所以這類問題比較簡單。只需要求
不可重疊的最長重複子串問題
有了不可重疊的限制稍微複雜一點,要用到
注意:這種分段的思想在後綴陣列相關問題中很常用
可重疊的 k 次最長重複子串
例:(JZOJ2265. 【Usaco DEC06 Gold】Milk Patterns)給定一個字串,求至少出現 k 次的最長重複子串。
做法和上面的差不多,還是先二分,但是條件改變了,不是不重疊,而是出現至少
子串計數問題
重複出現子串計數問題
例:(JZOJ1598. 檔案修復)求一個字串中有多少個至少出現兩次的子串
這是比較簡單的SA題,設每個字尾
不相同子串計數問題
例:(spoj694,spoj705)給定一個字串,求不相同的子串的個數。
和上面思路大相徑庭。每個字尾
字典序第K子串問題
例:(JZOJ2824. 【GDOI2012】字串)給出一個字串S,問該字串的所有不同的子串中,按字典序排第K的字串。
應該勉強算計數問題吧。。。其實就是不相同子串個數的擴充套件,算出每個字尾貢獻的不同子串個數,在二分找出最終子串位置(必然是某個字尾的字首)。
連續重複子串問題
連續重複子串問題
例:給定一個字串 L,已知這個字串是由某個字串 S 重複 R 次而得到的,
求 R 的最大值。
比較簡單的重複子串問題。列舉串
重複次數最多的連續重複子串問題
例:給定一個字串
還是列舉子串長度
多個字串相關問題
常用做法是將多個串連在一起,並且中間插入不同且沒出現過的字元隔開(想一想為什麼?)。但是這種題比較多變,不太好總結,只能簡述一些例子。
一個字串在所有字串中出現次數問題
例:(JZOJ3258. 【TJOI2013】單詞)給定
對於當前字串
字串子串重複出現k次問題
例:(JZOJ3975. 串)給定你n個字串,詢問每個字串有多少子串(不包括空串)是所有n個字串中至少k個字串的子串(注意包括本身)
SA+線段樹維護,詳見題解。
其他相關問題
字串不同種連續子串問題
例:(JZOJ4473. 生成魔咒)給定
仔細分析,這題要減去前面的操作對當前影響(即重複的連續子串)。這個應該算是“字首陣列”吧。具體來說就是將字串翻轉後求一邊SA,此時所得就是原串的字首陣列。然後線上段樹維護一下。
後記
這篇部落格是在複習之餘碼的,由於水平有限,難免有疏漏之處,歡迎批評和補充。後續(或許)會有例題及應用的補充。
參考資料:羅穗騫《字尾陣列——處理字串的有力工具》
以上.