1. 程式人生 > >字尾陣列應用小結

字尾陣列應用小結

前言

之前學了字尾陣列,這真是一個神奇的東西。早就想總結一些SA的應用,但一直沒時間,現在終於抽出空來寫一下自己的心得。
本文只討論字尾陣列的一些應用,不一定全面,僅供參考
還不會後綴陣列的同學請自學後再看本文,這裡不再贅述字尾陣列的基礎實現
推薦一篇部落格,裡面對於基礎的字尾陣列總結的比較到位,YxuanwKeith大神的五分鐘搞懂字尾陣列!字尾陣列解析以及應用
請不要吐槽標題,不知道你五分鐘搞不搞得懂,反正我搞不懂 = = 。
下面進入正題。

字尾陣列相關應用

單個字串相關問題

比較常見的思路是先構造字尾陣列,然後求Height陣列,用這兩個來求解。

重複子串問題

可重疊的最長重複子串問題

因為可重複,所以這類問題比較簡單。只需要求Height陣列的最大值。因為Height[i]表示排名為ii1的字尾的LCP,所以這個LCP一定是重複的,只需要求個最大值就是最長的。時間複雜度是線性的。

不可重疊的最長重複子串問題

有了不可重疊的限制稍微複雜一點,要用到Height陣列的性質。先二分答案,將問題轉化為判定性問題。假設我們二分的長度為k,那麼答案的兩個串它們在SA中的之間的Height值都會k(想一想為什麼?),所以我們把連續一段Heightk的字尾劃分成一段,如果有某一段滿足段中最大的SA值與最小值之差大於等於k,那麼當前解就是可行的,因為滿足這一條件的串一定不重疊。
注意:這種分段的思想在後綴陣列相關問題中很常用

可重疊的 k 次最長重複子串

例:(JZOJ2265. 【Usaco DEC06 Gold】Milk Patterns)給定一個字串,求至少出現 k 次的最長重複子串。
做法和上面的差不多,還是先二分,但是條件改變了,不是不重疊,而是出現至少k次。只需判斷當前段內是否出現k個字尾即可。

子串計數問題

重複出現子串計數問題

例:(JZOJ1598. 檔案修復)求一個字串中有多少個至少出現兩次的子串
這是比較簡單的SA題,設每個字尾Ranki,其最多能貢獻Height[i]Height[i1]個不同重複子串。
Ans=max(Height[i]Height[

i1],0)

不相同子串計數問題

例:(spoj694,spoj705)給定一個字串,求不相同的子串的個數。
和上面思路大相徑庭。每個字尾k會產生nSA[k]+1個字首,但是會重複計數,所以要減去前面相同的字首,最後就是nsa[k]+1height[k]個子串。

字典序第K子串問題

例:(JZOJ2824. 【GDOI2012】字串)給出一個字串S,問該字串的所有不同的子串中,按字典序排第K的字串。
應該勉強算計數問題吧。。。其實就是不相同子串個數的擴充套件,算出每個字尾貢獻的不同子串個數,在二分找出最終子串位置(必然是某個字尾的字首)。

連續重複子串問題

連續重複子串問題

例:給定一個字串 L,已知這個字串是由某個字串 S 重複 R 次而得到的,
求 R 的最大值。
比較簡單的重複子串問題。列舉串S長度k,如果Rank[1]Rank[k+1]Height=|L|k那麼當前答案合法。

重複次數最多的連續重複子串問題

例:給定一個字串L,求重複次數最多的連續重複子串。
還是列舉子串長度k,看這個長度對應每個位置(即L[0],L[k],L[k2]...)之間的LCP是否等於k最長能擴到哪裡,就是重複出現次數。

多個字串相關問題

常用做法是將多個串連在一起,並且中間插入不同且沒出現過的字元隔開(想一想為什麼?)。但是這種題比較多變,不太好總結,只能簡述一些例子。

一個字串在所有字串中出現次數問題

例:(JZOJ3258. 【TJOI2013】單詞)給定N個字串,求每個字串在所有字串中出現的次數。
對於當前字串S,設其在總串中起始位置為ST[i],那麼我們在Height上二分割槽間[1,Rank[ST[i]]],[Rank[ST[i]]+1,n]內滿足Height|S|,這之間的字尾數量就是答案。

字串子串重複出現k次問題

例:(JZOJ3975. 串)給定你n個字串,詢問每個字串有多少子串(不包括空串)是所有n個字串中至少k個字串的子串(注意包括本身)
SA+線段樹維護,詳見題解。

其他相關問題

字串不同種連續子串問題

例:(JZOJ4473. 生成魔咒)給定n個操作,每個操作在字串S尾插入一個字元,求當前操作後共有多少不同種連續子串。
仔細分析,這題要減去前面的操作對當前影響(即重複的連續子串)。這個應該算是“字首陣列”吧。具體來說就是將字串翻轉後求一邊SA,此時所得就是原串的字首陣列。然後線上段樹維護一下。

後記

這篇部落格是在複習之餘碼的,由於水平有限,難免有疏漏之處,歡迎批評和補充。後續(或許)會有例題及應用的補充。
參考資料:羅穗騫《字尾陣列——處理字串的有力工具》

以上.