后缀自动机能识别字符串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 };