一個用SAM維護多個串的根號特技


一個用SAM維護多個串的根號特技

基本介紹

在多個串的字符串題中,往往會出現一類題需要用到某個子串是否在一些母串中出現。此時對於 \(\text{parent}\) 樹的 \(\text{right}\) 集合而言,問題並不關心某個具體位置而只關心是否有某個 \(\text{endpos}\) 在指定母串中。

那么對於 \(\text{parent}\) 樹上的來自同一個母串的節點而言,其對祖先的貢獻都是可以替代的,並不需要重復標記其某個祖先 \(\text{right}\) 集合中是否存在一個 \(\text{endpos}\) 來自這個母串。

於是我們維護來自這個母串的所有節點對 \(\text{parent}\) 樹的貢獻復雜度等價於所有來自這個母串的葉子節點在 \(\text{parent}\) 樹上的並的大小。(此處葉子指的是來自這個母串且其子樹內不存在來自這個母串節點的節點)

分析這些葉子在樹上的並的大小的具體規模,有一個顯然的上界就是 \(\sum_{i=1}^{n}2len_i-1\) ,其中 \(len_i\) 是第 \(i\) 個串的長度,對其建后綴自動機的節點數上界為 \(2len_i-1\) ,對 \(n\) 個串一起建可以得到這個顯然的上界。

觀察這棵並起來的樹的性質可以發現,這棵樹上的每一個節點的 \(\text{right}\) 集合都包含來自這個母串的 \(\text{endpos}\) ,而每個節點的父節點都是該節點所代表串的一個后綴且至少長度減少 \(1\) 。那么考慮這個串每一個前綴的最大貢獻就是這個前綴的長度,所以可以得到另外一個上界 \(len_i^2\)

假設這 \(n\) 個串的總長為 \(S\) ,那么 \(\sum_{i=1}^{n}2len_i-1\) 可以看做 \(2S\) ,所以對於每一個母串都維護貢獻的復雜度是 \(\sum_{i=1}^n \min(2S, len_i^2)\) ,且 \(\sum_{i=1}^n len_i = S\) 。根據均值不等式可以得到 \(n\)\(len_i\) 都取 \(\sqrt{2S}\) 時達到上界,總復雜度 \(O(S\sqrt{2S})\)

然而事實上后面那個下界不容易卡滿,因為你需要構造一個字符串其每一個前綴都能在 \(\text{parent}\) 樹上分支出最長的一條鏈,所以這個根號實際上跑起來比某些大常數的一個 \(log\) 做法還快。


例題

BZOJ3277 字符串

題意:給出 \(n\) 個字符串,對於每一個字符串求出其有多少個子串在至少 \(k\) 個字符串中出現過。

可以說是這個特技的模板題了,不過線段樹合並可以做 \(O(nlogn)\) ,這里就只說根號做法吧。建出后綴自動機后枚舉每一個串的葉子節點暴力往上跳給祖先節點出現在不同的母串的次數 \(+1\) 即可,已經被別的該串節點遍歷過就跳出,復雜度就是上述的 \(O(S\sqrt{2S})\)

NOI2018 你的名字

題意:對於每一個詢問串,求出其有多少個不同子串在母串的 \([L, R]\) 之間出現過。

將問題轉化為求有多少個子串在詢問串和母串的 \([L, R]\) 之間共同出現即可,暴力枚舉的同時額外加一個線段樹合並判是否在 \([L, R]\) 即可,復雜度 \(O(S\sqrt{2S}logS)\) 。不過套上 \(log\) 以后會因為第二個上界被卡高后被叉掉,但是 \(68pts\) 不需要線段樹合並判斷,可以確保通過。實際上3s內跑過了所有測試點

Sum of Squares of the Occurrence Counts 加強版

沒加強之前這個特技不能做

題意:給出 \(n\) 個串,對於每一個串 \(i\) 求出其所有子串在串 \([1,i]\) 之間的出現次數的平方和。

對於所有串建后綴自動機,用線段樹合並維護出 \(\text{parent}\) 樹上每一個節點擁有來自哪幾種母串的 \(\text{endpos}\) ,以及每一種母串對應的 \(\text{endpos}\) 數量。考慮每一個母串對所有線段樹大小之和的貢獻就是葉子的並,於是暴力遍歷合並后的每一棵線段樹的總復雜度就是 \(O(S\sqrt{2S})\) 。直接在線段樹上暴力統計每一個 \(\text{parent}\) 樹上節點對每一個串的答案的貢獻即可,總復雜度 \(O(S\sqrt{2S}+SlogS)\)


后記

如果你想知道會了這個根號特技有什么用,我也說不清。對於我這種字符串菜雞來說,寫簡單好寫的做法比套上各種數據結構好調多了,這個特技犧牲了一些時間效率,但是大大簡化了思維難度和代碼難度。當然如果您是神仙完全可以去秒正解。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM