SAM-字尾自動機
字尾自動機
毒液哥 Fudan University
引論
字尾自動機(Suffix Automaton, SAM)是基於字尾匹配的字尾資料結構中一種功能強大的資料結構。
作為一個能接受字串所有子串的有限狀態自動機,字尾自動機構建的時空複雜度均只需要
, 其中
為字串長度,且字符集大小
為常數。
下文將會討論字尾自動機的基本定義和構造以及複雜度分析,並結合例題來分析其作為自動機以外的性質。
字尾自動機
定義
在字串領域中,一個自動機有如下構成:
- 狀態
- 轉移
- 一個初始狀態
- 至少一個接受狀態
- 字符集
而有限狀態自動機(Finate-State Automaton, FSA)的狀態和轉移數均是有限的。
若將狀態視作點,將轉移視作有向邊,則FSA可以用一個有向圖表示。
FSA可以讀入一個字串並且,從初始狀態開始,依次沿著字串的每個字元在當前狀態的轉移,轉移到下一個狀態,並最終停留在一個狀態上。若該狀態是一個接受狀態,則稱這個字串可以被這個FSA所接受。而後綴自動機是由長度為 的字串 構造的一個狀態數為 ,轉移數為 的能接受 所有子串的FSA.
考慮一個樸素的能接受 的所有子串的FSA,對所有不同的子串都建立一個狀態,那麼轉移易得,且所有狀態均是接受狀態。
對於一個長度為 的字串 , 我們作如下記號:
- 表示 中從左往右數第 個字元。
- 表示 中以 開頭, 結尾的子串。
- 表示以 結尾的 的字首,即 。
- 表示以 開頭的 的字尾,即 。
- 表示 在 中出現位置的結尾座標構成的集合。
- 表示 在 中出現位置的結尾座標構成的集合。
- 表示將字串(字元) 和字串(字元) 拼接在一起得到的字串。
根據定義我們可以得到如下性質1:對於 的兩個子串 , 若 和 有交集,則必有 或 , 不妨設 ,則 是 的一個字尾。
定義 等價類:若兩個狀態(子串)的 集合相等,則他們屬於同一個 等價類。
樸素的FSA中狀態數為 ,是我們無法接受的,因此必須考慮將某些狀態合併在一起。
若將一個 等價類中的元素按長度遞減排序,則每個字串都是前一個的字尾。若其中的某個狀態無法轉移字元 ,因為等價類中所有字串的結尾均相同,且出現位置也都相同,該等價類中所有子串均無法轉移 ;同理,若某個狀態可以轉移字元 ,則該等價類中所有子串均可以轉移 . 我們發現,一個 等價類中所有狀態的轉移是相同的。因此可以一個 等價類合併成一個狀態。對於這樣一個狀態 ,我們定義合併之前最長的字串為 , 最短的為 , 的長度為 .
定義 的字尾連結:一個 的 ,使得 , 則 為 的字尾連結,記為 . 由前述性質可得, 狀態中所有子串均是 中任意子串的字尾。
性質2:在
無法轉移字元
時,
有可能轉移
,因為
佳媛姐姐過生日的時候,她的小夥伴從某東上買了一個生日禮物。生日禮物放在一個神奇的箱子中。箱子外邊寫了 一個長為\(n\)的字串\(s\),和\(m\)個問題。佳媛姐姐必須正確回答這\(m\)個問題,才能開啟箱子拿到禮物,升職加薪,出任CE O,嫁給高富帥,走上人生巔峰。每個問題均有\(a,b,c,d\)四個引
字尾自動機
毒液哥 Fudan University
引論
字尾自動機(Suffix Automaton, SAM)是基於字尾匹配的字尾資料結構中一種功能強大的資料結構。 作為一個能接受字串所有子串的有限狀態自動機,字尾自動機構建的時空複雜度均只需要
這是一篇其實理解並不深刻只會打板子的蒟蒻寫出的總結
分成幾個板塊吧。。。。。。
1.檢查字串是否出現
給一個文字串 \(T\) 和多個模式串 \(P\),我們要檢查字串 \(P\) 是否作為 \(T\) 的一個子串出現。
對 \(T\) 建出 \(SAM\)
直接在後綴樹上從根開始往下走,
題目傳送門
做法:
我們知道SAM中 l[st] 陣列的意義是狀態st的最長子串的長度
從前一狀態到當前狀態的轉移所增加的子串數量:
l[st] - l[slink[st]]
AC程式碼:
#inc
傳送門
解析:
這道題可以把所有串接在一起構建字尾自動機來做,但是那樣還不如寫字尾陣列。。。
所以這裡提供一個只有字尾自動機能實現的做法。
思路:
首先構建出第一個串的字尾自動機。
然後拿其他的串放到字尾自動機上面跑。同時更新答案。
程式碼裡面的
傳送門
解析:
小聲BB:vjudge上面應該出了一點問題,C++會Language Erro,C++14就沒有問題。
思路:
建立其中一個串的SAM,然後拿另外一個串去匹配,能夠匹配到的最大長度就是最長公共子串。
啊你問我為什麼這樣是對的,請回去重新學習什麼是
傳送門
解析:
SAM基礎操作。
解析:
其實不管其他的單獨看字尾連結,即
f
a
參考題目:洛谷P3804
解析:
其實這個東西的理解的話,說難沒有那麼難,說簡單也不是很簡單。 這裡先貼一個程式碼,什麼時候再更新吧。
程式碼:
#include<bits/stdc++.h>
using namespace std;
#defin
這是一篇偷懶的文章,主要是今天確實碰到了比較難理解的資料結構。 之前是以為所有的字尾自動機都可以用字尾陣列代替的,今天做到有一道題hdu6405,似乎並非如此了,主要這題是多串的,所以沒法子字尾陣列,只能字尾自動機(而且還是廣義字尾自動機,相關題解明天補上) 今天參考的博文 傳送門A
引入
來吧字尾自動機 我們先來看一看字尾陣列可以幹一些什麼事情
1.可以檢視當前字尾在所有後綴的排名
2.可以看最大的相同子串
但是缺點呢卻也非常的明顯——顯然這tm是個靜態的。。。。
於是只好另闢蹊徑——字尾自動機
我們來看看字尾自動機可以幹一些什 正好寫這個部落格和我的某個別的需求重合了。。。我就來講一講SAM啦qwq
字尾自動機,也就是SAM,是一種極其有用的處理字串的資料結構,可以用於處理幾乎任何有關於子串的問題,但以學起來異常困難著稱(在機房裡,最先學會SAM的永遠是大佬(比如litble和zyf(他在退役前就學了)))。
但是!!!當你學了
/* ***********************************************
Author :kuangbin
Created Time :2013-9-8 23:27:46
File Name :F:\2013ACM練習\專
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#defin 題意
給定兩個字串,求兩個字串相同子串的方案數。
分析
那麼將字串s1建SAM,然後對於s2的每個字首,都在SAM中找出來,並且計數就行。
我一開始的做法是,建一個u和len,順著s2跑SAM,當st[u].next[c]存在的時候,u=st[u].next[c], E - Three strings
將三個串加進去,看每個節點在三個串中分別出現了多少次。
#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk mak
題目描述
給定一個只包含小寫字母的字串SS,
請你求出 SS 的所有出現次數不為 11 的子串的出現次數乘上該子串長度的最大值。
輸入輸出格式
輸入格式:
一行一個僅包含小寫字母的字串SS
輸出格
3998: [TJOI2015]弦論
Time Limit: 10 Sec Memory Limit: 256 MB Submit: 4251 Solved: 1562 [Submit][Status][Di
Musical Theme
Time Limit: 1000MS Memory Limit: 30000K
題目大意: 給定一個串,找出滿足條件最長子串: 1,長度大於等於5 2,至少出現兩次 3,至少有兩個出現位置不重疊
子串不一定要嚴格相等,兩兩差值相等即可。
3998: [TJOI2015]弦論
Description
對於一個給定長度為N的字串,求它的第K小子串是什麼。
Input
第一行是一個僅由小寫英文字母構成的字串S 第二行為兩個整數T和K,T為0則表示不同位置的相同子串算作一個。T=1則表示不同位置的相同子串算作多
如果對字尾自動機有一定了解,這幾篇文章對你可能會有些許幫助: menci’s字尾自動機學習筆記 字尾自動機學習指南 loj上的字尾自動機講解 一些題目 聽說對拆點講解很詳細 127~132周
以題目為主,當然也有一些講解。下面說一下我對字尾自動機的理解,不給出詳細證明。 相關推薦
字串(tjoi2016,heoi2016,bzoj4556)(sam(字尾自動機)+線段樹合併+倍增+二分答案)
SAM-字尾自動機
SAM(字尾自動機)專題總結
[Hihocoder](1445)字尾自動機二·重複旋律5 ----SAM構造
2018.12.15【SPOJ-LCS2】Longest Common Substring II(字尾自動機SAM)
2018.12.15【SPOJ-LCS】Longest Common Substring(字尾自動機SAM)
2018.12.15【HDU4622】Reincarnation(字尾自動機SAM)
【模板】字尾自動機SAM
【字尾自動機】【SAM】學習相關以及模板
【字尾自動機】【SAM】【自動機】【資料結構】字尾自動機理解(入門)
字尾自動機(SAM)速成手冊!
SPOJ 1811. Longest Common Substring (LCS,兩個字串的最長公共子串, 字尾自動機SAM)
Codeforces Round #146 (Div. 1) C - Cyclical Quest 字尾自動機+最小迴圈節
【BZOJ4566】找相同字元【字尾自動機】
MemSQL Start[c]UP 2.0 - Round 1 E - Three strings 廣義字尾自動機
洛谷P3804 字尾自動機
BZOJ 3998: [TJOI2015]弦論 字尾自動機
Musical Theme(字尾自動機)
[TJOI2015]弦論(字尾自動機)
字尾自動機概述