关于 SAM:
- lnk 树上,任意非叶子节点,其孩子节点的 endpos 集合是本身 endpos 集合的划分。
- SAM 的 lnk 树是“前缀树”,任意节点是其孩子节点的后缀。
void insert(int c) {
int p = lst, np = ++ct;
len[np] = len[p] + 1, siz[np] = 1, lst = np;
for (; p && !kid[p][c]; p = lnk[p]) kid[p][c] = np;
if (!p) lnk[np] = 1;
else {
if (len[p] + 1 == len[kid[p][c]]) lnk[np] = kid[p][c];
else {
int q = kid[p][c], nq = ++ct;
len[nq] = len[p] + 1, lnk[nq] = lnk[q], lnk[q] = lnk[np] = nq;
memcpy(kid[nq], kid[q], sizeof(kid[q]));
for (; p && kid[p][c] == q; p = lnk[p]) kid[p][c] = nq;
}
}
}