字符串abcbc的后缀自动机:
endpos: 表示结束位置的集合。
a b c b c
1 2 3 4 5
b: [2, 4], b: [3, 5] == bc: [3, 5],所以b和bc是等价类
后缀自动机所有结点的数量 ≤ 2 * n - 1。
abcbc等价类:
画aababa的等价类图
void insert(char c) { int p = last, np; np = last = ++ tot; maxL[np] = maxL[p] + 1; for( ; p && !go[p][c]; p = fa[p]) go[p][c] = np; if(!p) fa[np] = 1; else { int q = go[p][c]; if(maxL[p] + 1 == maxL[q]) fa[nq] = q; else { int nq = ++ tot; maxL[nq] = maxL[p] + 1; for( ; p && go[p][c] == q; p = fa[p]) go[p][c] = nq; for(int i = 0; i < 26; i ++) go[nq][i] = go[q][i]; fa[nq] = fa[q]; fa[np] = fa[q] = nq; } } }
void extend(int c) { int p = last, np = last = ++ tot; f[tot] = 1; node[np].len = node[p].len + 1; for (; p && !node[p].ch[c]; p = node[p].fa) node[p].ch[c] = np; if (!p) node[np].fa = 1; else { int q = node[p].ch[c]; if (node[q].len == node[p].len + 1) node[np].fa = q; else { int nq = ++ tot; node[nq] = node[q], node[nq].len = node[p].len + 1; node[q].fa = node[np].fa = nq; for (; p && node[p].ch[c] == q; p = node[p].fa) node[p].ch[c] = nq; } } }