Sam小结和模板

Sam 的一些总结

注意在子串在某个节点的性质,其 father 上也会有相同的性质

1. 统计子串出现的次数

  • \(parent\) 树上做 \(dp\),对于每一个节点,初始化为 \(dp[i] = 1\),然后 \(dp[father] = \sum dp[son]\)

2. 子串的个数

  • 利用后缀数组,\(\sum_{i=2}^{n} len-sa[i]+1-height[i]\) 就是答案
  • 利用后缀自动机,\(dp[i]\) 表示第 \(i\) 个节点拥有的字符串个数,可以让 \(v \in u'next\)\(dp[u] = \sum dp[v]\),最后的 \(dp[1]-1\) 就是答案。
  • 利用后缀自动机,\(\sum_{i=2}^{sz} node[i].len - node[father].len\) 就是答案。

3. 子串出现的最左和最后位置

  • 在构建后缀自动机的时候,令 \(left[np] = right[np] = id\),如此可以求出最左位置。
  • \(parent\) 树上跑,\(right[father] = max(right[father], right[son])\),如此可以求出最右位置。

4. 求 LCS

  • 每次匹配的的时候看当前匹配的时候 \(p\) 有没有往一条 \(char\) 的边,没有的话往 \(fa[p]\),如果一直跳到 \(p=0\),就重新赋值 \(p=1,res=0\),否则就往 \(node[p][char]\) 跳,并让 \(res++\)
  • 求多个字符串的时候,就要考虑往 \(father\) 上的更新。

5. 求字典序第 k 小

  • \(dfs\) 出每个节点往后有多少子串,然后从小到大在 \(dfs\) 一边找到第 \(k\) 大。
  • 如果 \(v\) 往后的字符串比 \(k\) 小,那么直接 \(k-cnt[v]\)
  • 否则往下走一步,并让 \(k-\)\(-\)

6. Sam 上的基数排序

 for(int i=0; i<=sz; i++)    tax[i] = 0;
 for(int i=1; i<=sz; i++)    tax[step[i]]++;
 for(int i=1; i<=sz; i++)    tax[i] += tax[i-1];
 for(int i=1; i<=sz; i++)    gid[tax[step[i]]--] = i;

7. Sam模板

struct Sam {
    int node[maxn][27], fa[maxn], step[maxn];
    int sz, last;
    int newnode() {
        mes(node[++sz], 0);
        fa[sz] = step[sz] = 0;
        return sz;
    }
    void init() {
        sz = 0;
        last = newnode();
    }
    void insert(int k) {
        int p = last, np = last = newnode();
        step[np] = step[p]+1;
        for(; p&&!node[p][k]; p=fa[p])
            node[p][k] = np;
        if(p==0) {
            fa[np] = 1;
        } else {
            int q = node[p][k];
            if(step[q] == step[p]+1) {
                fa[np] = q;
            } else {
                int nq = ++sz;
                memcpy(node[nq], node[q], sizeof(node[q]));
                fa[nq] = fa[q];
                step[nq] = step[p]+1;
                fa[np] = fa[q] = nq;
                for(; p&&node[p][k]==q; p=fa[p])
                    node[p][k] = nq;
            }
        }
    }
} sam;

猜你喜欢

转载自www.cnblogs.com/Jiaaaaaaaqi/p/10987468.html
SAM