SAM(后綴自動機)總結


“寫sam是肯定會去寫的,這樣才學的了字符串,后綴數組又不會用 >ω<,

sam套上數據結構的感覺就像回家一樣!

里面又能剖分又能線段樹合並,調試又好調,我愛死這種寫法了 !qwq”

SAM是一個DFA,它存儲了某字符串的所有子串信息。

待更。

博主水平不行,盡量在退役前多更些。

插入字符:

 1 void extend(int id,int&now)
 2 {
 3     int p=now;
 4     if(ch[p][id] && len[ch[p][id]]==len[p]+1)
 5     {
 6         now=ch[p][id];
 7         return;
 8     }
 9     int np=++tot;
10     len[np]=len[p]+1;
11     while(p && !ch[p][id])
12     {
13         ch[p][id]=np;
14         p=fa[p];
15     }
16     if(!p)
17     {
18         fa[np]=1;
19     }
20     else
21     {
22         int q=ch[p][id];
23         if(len[q]==len[p]+1)
24         {
25             fa[np]=q;
26         }
27         else
28         {
29             int nq=++tot;
30             len[nq]=len[p]+1;
31             fa[nq]=fa[q];
32             for(int i=0;i<26;i++)
33                 ch[nq][i]=ch[q][i];
34             fa[q]=fa[np]=nq;
35             while(p && ch[p][id]==q)
36             {
37                 ch[p][id]=nq;
38                 p=fa[p];
39             }
40         }
41     }
42     now=np;
43 }

套路:

每條路徑與子串一一對應。

$len_i$:該節點最長串的長度

$Parent Tree$上的子樹和:串的出現次數

$len_i - len_{fa_i}$:該節點代表的串的數目

部分題目選:

(1)[SAM入門題][NOI2018]你的名字

題目鏈接

線段樹合並維護$right$集合

(2)[SAM入門題][CTSC2012]熟悉的文章

題目鏈接

$SAM$只是用來預處理的,求答案還要靠二分+單隊$DP$

(3)[SAM入門題][bzoj2555]Substring

題目鏈接

$LCT$對$Parent Tree$結構的維護

(4)[bzoj3277]字符串

題目鏈接

廣義后綴自動機的應用

暴力搞復雜度大概是根號的,不會證明。

(5)[bzoj5084]HASHIT

題目鏈接

帶撤銷后綴自動機,隨機數據隨便艹。

upd:BFS建樹形后綴樹以后再進行DFS+樹鏈求並統計答案就行了。

(6)[USACO]牛奶模式

題目鏈接

后綴自動機的基本原理與使用

(7)[洛谷元旦賽]WD與數列

題目鏈接

維護$right$集合的好題(似乎還要在parent樹上跑啟發式合並計算貢獻,我並不會)

現在可能會了。

(8)[FZOJ2258]封印

校內題目,沒連接

大概就是你知道$Parent$樹是干啥的,形態如何,就能直接切掉。

(9)[TJOI2016]字符串

考慮求出 sam 上一個串 p 在 [l,r] 里出現的次數,這個可以通過數一數 p 的 right 集合里有多少在 $[l+len_p-1,r]$ 中出現。

lcp 可以二分,倍增可以從區間 locate 子串,那么這個題就 $O(n\log^2 n)$ 了。

upd:話說為啥沒見過把狀態設在sam節點上的DP題?

upd:CF700E,已經單獨更新

(10)[十二省聯考]字符串問題

題目意思大概是描述給你一個連邊關系,求 DAG 上最長路。

直接暴力構圖可以 $n^2$ ,用 hash 判斷。

如果考慮建后綴樹,那么在一個節點上有短->長的后綴關系,另外父子關系也是后綴關系,拆點據此連邊即可。

只需要實現對區間 locate 子串即可,時間復雜度 $O(n\log n)$。


免責聲明!

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



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