SAM

后缀自动机能识别字符串S的所有子串,是一个DAG。

http://blog.csdn.net/huanghongxun/article/details/51112764

https://blog.xehoth.cc/SuffixAutomation/#一些性质

hihocoder上的一堆SAM入门教程挺友好的。

附SAM模板

 1 const int N = 1e6+10;
 2 struct SAM{
 3     //pre[]: parent树, pre[i]是i的后缀, 字符串长度小于i
 4     //son[][]: trans DAG图
 5     //ml[]: maxlen, min[i] = max[pre[i]]+1, 不同的字符串个数是maxlen-minlen+1
 6     int tot, last, pre[N<<1], son[N<<1][26], ml[N<<1];
 7     void init() {
 8         tot = 1, last = 1;
 9         memset(son[1], 0, sizeof son[1]);
10     }
11     void extend(char c){
12         int w = c-'a', p = ++tot, x = last, r, q;
13         memset(son[p], 0, sizeof son[p]);
14         for(ml[last = p] = ml[x]+1; x&&!son[x][w]; x = pre[x]) son[x][w] = p;
15         if(!x) pre[p] = 1;
16         else if(ml[x]+1 == ml[q = son[x][w]]) pre[p] = q;
17         else{
18             pre[r = ++tot] = pre[q];
19             memcpy(son[r], son[q], sizeof son[r]);
20             ml[r] = ml[x]+1;
21             pre[p] = pre[q] = r;
22             for(; x&&son[x][w] == q; x = pre[x]) son[x][w] = r;
23         }
24     }
25 };
View Code

相关文章: