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/
时间: 2024-12-25 04:21:56