struct SAM {
int ch[M][26], par[M], ml[M];
int siz, rt, last;
inline void set() {
siz = rt = last = 1;
memset(ch, 0, sizeof ch);
memset(par, 0, sizeof par);
memset(ml, 0, sizeof ml);
}
inline void extend(int c) {
int p = last, cur = ++siz; // 新建节点 cur
ml[cur] = ml[p] + 1; // 新建节点的 maxlen 是上一个节点的 maxlen + 1
for (; p && !ch[p][c]; p = par[p]) ch[p][c] = cur;
// 沿着 suffix-link 找到第一个非空的 state ,沿途设置转移 trans(x, c) = cur
if(!p) par[cur] = rt; // 如果没有被占用的 state,那么 suffix-link 连到 empty-state,也就是 root
else {
int q = ch[p][c]; // 原来连到的点 q
// 由于 maxlen[p] + 1 = minlen[q], 所以不可能存在 maxlen[p] + 1 > maxlen[q]
if(ml[q] == ml[p] + 1) par[cur] = q;
// 如果恰好等于 maxlen[p] + 1,那么就什么也不用设置了,suffix-link 连到 q 即可(因为已经包含之后所有 suffix 了)
else { // maxlen[p] + 1 < maxlen[q]
int sq = ++siz; // 新建辅助节点 sq
par[sq] = par[q];
for (int i=0; i<26; ++i) ch[sq][i] = ch[q][i];
// 复制 q 的信息到 sq
ml[sq] = ml[p] + 1; // 分裂成两部分,前半部分sq,后半部分q
par[q] = par[cur] = sq; // 把 q 和 cur 的 suffix-link 都设为 sq
for (; p && ch[p][c] == q; p = par[p]) ch[p][c] = sq;
// 把原来到 q 的 transition 改为到 sq
}
}
last = cur;
}
}S;
代码实现参考:http://www.cnblogs.com/candy99/p/6374177.html
SAM教程推荐:https://huntzhan.org/suffix-automaton-tutorial/