一、 S A M SAM SAM的性质:
-
S A M SAM SAM是一个状态机。一个起点,若干终点。原串的所有子串和从 S A M SAM SAM起点开始的所有路径一一对应,不重不漏。所以终点就是包含后缀的点。
-
每个点包含若干子串,每个子串都一一对应一条从起点到该点的路径。且这些子串一定是里面最长子串的连续后缀。
-
S A M SAM SAM问题中经常考虑两种边(绿边和蓝边)
-
- 普通边:类似于 T r i e Trie Trie。表示在某个状态所表示的所有子串的后面添加一个字符。(蓝边)
-
- L i n k , F a t h e r Link, Father Link,Father. 表示某个状态所表示的最短子串的首字母删除。这类边构成一颗树(绿边)(由于绿边的特殊性,每次动态插入时,都可能会改变 绿边的连向)
二、 S A M SAM SAM的构造思路
- e n d p o s ( s ) endpos(s) endpos(s): 子串s所有出现的位置(尾字母下标)集合。 S A M SAM SAM中的每个状态都一一对应一个 e n d p o s ( s ) endpos(s) endpos(s)的等价类
- e n d p o s endpos endpos 的性质
-
- 另 s 1 , s 2 s1,s2 s1,s2为 s s s的两个子串, 不妨设 ∣ s 1 ∣ ≤ ∣ s 2 ∣ |s1| \leq |s2| ∣s1∣≤∣s2∣。则 s 1 s1 s1 是 s 2 s2 s2的后缀当且仅当 e n d p o s ( s 2 ) ⊆ e n d p o s ( s 1 ) endpos(s2) \subseteq endpos(s1) endpos(s2)⊆endpos(s1), s 1 s1 s1 不是 s 2 s2 s2的后缀当且仅当 e n d p o s ( s 1 ) ∩ e n d p o s ( s 2 ) = ∅ endpos(s1) \cap endpos(s2) = \emptyset endpos(s1)∩endpos(s2)=∅
-
- 两个不同子串的 e n d p o s endpos endpos,要么有包含关系,要么没有交集。
-
- 两个子串的 e n d p o s endpos endpos相同,那么短串为长串的后缀。
-
- 对于一个状态st,以及任意的 l o n g e s t ( s t ) longest(st) longest(st)的后缀 s s s,如果 s s s的长度满足: s h o r e s t ( s t ) ≤ ∣ s ∣ ≤ l o n g e s t ( s t ) shorest(st) \leq |s| \leq longest(st) shorest(st)≤∣s∣≤longest(st), 那么 s ∈ s u b s t r i n g ( s t ) s \in substring(st) s∈substring(st).
三、 S A M SAM SAM的构造过程
- 分类讨论。。。。
- 证明略。。
四、 S A M SAM SAM时间复杂度
- 线性 o ( n ) o(n) o(n),记得开两倍内存
- 证明复杂,略。。。。
五、 S A M SAM SAM常见问题分析
- 求不同子串的数量
1 丹爷的模板题(模板看这个) - 每个子串出现的次数。
1 acwing的一道模板题(模板看这个) - 求lcm的一个应用
1 acwing的一道题
六、 more,挖一个坑(等cf分数上去再补吧,现在这个超出我的水准)
菜鸡只配切模板题,下面的是bt难度题目。
cf2500+以上。。。。。。。。。。。。。。。。。。。
- H. Security SAM and 线段树。
一个大佬的题解 - E. Three strings(广义SAM)
一个大佬的题解 - P3346 [ZJOI2015]诸神眷顾的幻想乡(tire树上的广义SAM)
一个大佬的题解 - [USACO17DEC]Standing Out from the Herd P (广义SAM或后缀数组容斥)
一个大佬的题解 - P4094 [HEOI2016/TJOI2016]字符串 字符串(二分+SAM上线段树合并)
一个大佬的题解