首页 > 代码库 > 后缀自动机详细理解

后缀自动机详细理解

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/

后缀自动机详细理解