我們考慮將乙個串的所有字尾插入乙個trie中,得到的trie就是字尾trie。我們可以發現,樹上有分叉或者是字尾節點的點的個數是o(l
en
)o(len)
o(len)
個,這個後面解釋,於是把沒有分支並且不是字尾節點的點壓縮到一起,就變成了字尾樹。
不難發現,字尾樹可以表示該字串的所有子串。
下面分析一下字尾樹的一些性質
字尾樹乙個節點表示的串出現次數相同。(不然為什麼能縮到一起)。
字尾樹按照『a』 - 『z』遍歷得到的dfs序就是將原串所有子串按照字典序從小到大排序得到的序列。
有人會問,為什麼有字尾樹,沒有字首樹?我只能說,呵呵。
不會正常的o(n
logn
)
o(nlogn)
o(nlog
n)構造,但是我們可以通過構造字尾自動機來構造,實際上我們知道,乙個串字尾自動機的parent樹,實際上就是其反串的字尾樹,由於字尾自動機節點是o(l
en)
o(len)
o(len)
的,所以字尾樹節點也是o(l
en)
o(len)
o(len)
的。利用字尾樹可以輕鬆的解決一些與字典序相關的問題,這裡隨便說一下,比如查詢字典序排第k大的是那個,很明顯,二分。如果查詢某個串的排名,先走到對應節點,然後看這個節點的dfs序之類的就可以了。
我們將所有字尾排序,得到乙個序列,設為sa,sa[i]表示排名為i的串是那個字尾,由於字尾長度互不相同,所以排序結果唯一。字尾排序可以通過剛才建字尾樹的方法,可以不去寫網上常見的倍增做法。
再定義hei
ght[
i]=l
cp(s
[sa[
i−1]
,n],
s[sa
[i],
n]
)height[i] = lcp( s[sa[i - 1] ,n] , s[sa[i] , n] )
height
[i]=
lcp(
s[sa
[i−1
],n]
,s[s
a[i]
,n])
,以及rnk
[i]=
字尾i的
排名
rnk[i] = 字尾i的排名
rnk[i]
=字尾i
的排名。
我們可以知道hei
ght[
rnk[
i]]≥
heig
ht[r
nk[i
−1]]
−1
height[rnk[i]] \geq height[rnk[i-1]] - 1
height
[rnk
[i]]
≥hei
ght[
rnk[
i−1]
]−1,然後就可以計算height了。至於有什麼用,主要用處就是hei
gh
theight
height
。但是博主太菜,沒找到什麼只能用字尾陣列,而不能用字尾樹或者字尾自動機搞的題目,或者用字尾陣列明顯好做的題目,望有人告知博主。
字尾樹 字尾陣列
在字串處理當中,字尾樹和字尾陣列都是非常有力的工具,其中字尾樹大家了解得比較多,關於字尾陣列則很少見於國內的資料。其實字尾陣列是字尾樹的乙個非 常精巧的替代品,它比字尾樹容易程式設計實現,能夠實現字尾樹的很多功能而時間複雜度也不太遜色,並且,它比字尾樹所占用的空間小很多。可以說,在資訊學競賽 中字尾...
字尾樹與字尾陣列
字尾樹和字尾陣列是字串處理的兩大神器,幾乎可處理掉一切的字串處理問題,但是在實際中,字尾陣列比字尾樹更好寫 好調,同時時間上也不差 常數很小 所以字尾陣列絕對是oi競賽之必備神器。字尾樹,實際上就是一棵字典樹。考慮將某個串 s 的所有字尾插到一棵trie裡,那麼我們就得到了一棵字尾樹。在這裡,我們不...
字尾陣列入門,字尾陣列模板整理
我自己懶得寫,就是想寫個部落格儲存下大佬的部落格位址 點這模板題 大佬的模板 include include include include include include include include include include include define inf 0x3f3f3f3f d...