后缀数组SA
后綴數組SA
模板
花了不少時間才理解倍增求SASASA的實現方法,我還是太菜了。
定義sa[i]sa[i]sa[i]表示排名為iii的后綴的起始位置。
定義rank[i]rank[i]rank[i]表示起始位置為iii的后綴的排名。
顯然兩者之前互逆。
Height以及LCP
定義LCP(x,y)LCP(x,y)LCP(x,y)表示字符串xxx與yyy之間的最長公共前綴長度。
定義height[i]height[i]height[i]表示suffix[sa[i?1]]suffix[sa[i-1]]suffix[sa[i?1]]和suffix[sa[i]]suffix[sa[i]]suffix[sa[i]]的LCPLCPLCP的長度,即相鄰排名的后綴的LCPLCPLCP長度。
容易發現一個性質
對于任意的j,kj,kj,k,若rank[j[<rank[k]rank[j[<rank[k]rank[j[<rank[k],則suffix(j),suffix(k)suffix(j),suffix(k)suffix(j),suffix(k)的LCPLCPLCP的長度為
mini=rank[j]+1rank[k]height[i]min_{i=rank[j]+1}^{rank[k]}height[i] mini=rank[j]+1rank[k]?height[i]
即兩個后綴j,kj,kj,k的LCPLCPLCP長度是排名在它們之間所有的后綴(包括suffix(k)suffix(k)suffix(k))的heightheightheight值的最小值。
根據這一性質,倘若我們可以求出height[i]height[i]height[i],我們就可以通過STSTST表,O(nlgn)O(nlgn)O(nlgn)預處理,O(1)O(1)O(1)詢問兩個后綴的LCPLCPLCP答案了。
而對于heightheightheight數組,也有一個重要的性質:
height[i?1]?1≤height[i]height[i-1]-1\leq height[i] height[i?1]?1≤height[i]
于是可以O(n)O(n)O(n)計算heightheightheight了。
SA的簡單應用
1.求最長重復子串
答案為heightheightheight最大值。
2.求最長重復k次子串
二分答案,轉化為判斷是否存在長度為xxx的子串重復至少kkk次。將所有相鄰且heightheightheight大于等于xxx的都分在一組,判斷是否有一組的后綴個數大于kkk即可。
時間復雜度O(n)O(n)O(n)
3.本質不同子串個數
答案為產生的新串數量-重復出現的串的數量。
則∑i(n?i+1)?height[rnk[i]]\sum_{i} (n-i+1)-height[rnk[i]]∑i?(n?i+1)?height[rnk[i]]。
總結
- 上一篇: 怎么创建app软件(如何设计一个app软
- 下一篇: 模板怎么上传(醒图模板怎么上传)