zoukankan      html  css  js  c++  java
  • SAM(后缀自动机)专题总结

    这是一篇其实理解并不深刻只会打板子的蒟蒻写出的总结

    分成几个板块吧。。。。。。

    • 1.检查字符串是否出现

      给一个文本串 (T) 和多个模式串 (P),我们要检查字符串 (P) 是否作为 (T) 的一个子串出现。

    (T) 建出 (SAM)

    直接在后缀树上从根开始往下走,如果能走到 (P) 结尾说明是模板串的子串

    • 2.不同子串个数

      给一个字符串 (S),计算不同子串的个数。

    静态:我们知道每个子串就是后缀DAG上的一条路径

    DAG上路径数怎么统计就不用说了吧

    动态:每次新建一个节点,贡献为(len(np)-len(f(np)))

    好像挺显然的?

      例题:生成魔咒

    • 3.最小循环移位

    给定一个字符串 (S) 。找出字典序最小的循环移位

    发现字符串 (S+S) 包含字符串 (S) 的所有循环移位作为子串。

    所以问题变为在 (S+S) 对应的后缀自动机上寻找最小的长度为 |S| 的路径

    直接从初始状态开始,贪心地访问最小的字符即可。

      例题:工艺

    • 4.出现次数

    对于一个给定的文本串 (T) ,有多组询问,每组询问给一个模式串 (P) ,回答模式串 (P) 在字符串 (T) 中作为子串出现了多少次

    我们发现用如果模式串在 (SAM) 上跑匹配,那么最终到达的点的 (endpos) 就是该串的出现次数

    考虑 (endpos) 的处理根据定义发现其实就是后缀树上的子树大小

    所以我们把实点权值设为 (1),虚点设为 (0),跑拓扑就行了

     例题:(substring)(需要动态维护 (endpos),打棵 (lct) 呗)

    • 5.字典序第 k 大子串

    给定一个字符串 (S) 。多组询问,每组询问给定一个数 K​ ,查询 (S) 的所有子串中字典序第 K​ 大的子串。

    字典序第 (K) 大的子串对应于 (SAM) 中字典序第 (k) 大的路径

    那么在计算每个状态的路径数后,就可以从 (SAM) 的根开始找到第 (k) 大的路径。

     例题:弦论

    • 6.第一次出现的位置

    给定一个文本串 (T) ,多组查询。每次查询字符串 (P) 在字符串 (T) 中第一次出现的位置( (P) 的开头位置)。

    预处理出每个状态第一次出现的位置(pos(i))

    其实只需要让每次(pos(np)=len(np) pos(nq)=pos(q))就好了

    查询答案为(pos(i)-|T|+1)

    • 7.最短的没有出现的字符串

    给定一个字符串 (S) 和一个特定的字符集 (T),我们要找一个长度最短的没有在 (S) 中出现过的字符串

    (SAM) 上做 (dp)

    (dp_i) 表示到点 (i) 时的最短长度

    如果这个点有不是 (T) 中字符的出边,则 (dp_i=1),否则 (dp_i=1+minlimits_{(i,j,c)in SAM}dp_j)

    • 8.两个字符串的最长公共子串

    给定两个字符串 (S)(T) ,求出最长公共子串。

    直接把 (T) 扔到 (S) 的自动机上跑匹配就行了

    • 9.求 (endpos) 集合

    给定一个字符串 (S),求 (endpos) 集合

    首先我们能够求出每个节点的 (pos)

    然后发现一个点的 (endpos) 就是他子树的 (pos) 的集合

    怎么让一个点带上整个子树的某个值? 主席树合并啊!

    每个点初始在主席树上插入 (pos(i))

    然后拓扑合并就行了

      例题:你的名字

  • 相关阅读:
    性能参考指标
    Java Native Interface 二 JNI中对Java基本类型和引用类型的处理
    Java Native Interface 编程系列一
    HTTP的报文与状态码
    [译]Android调整图像大小的一些方法
    Android多线程通信机制
    Android四大组件知识整理
    Java多态与反射
    23种设计模式的优点与缺点概况
    Android应用性能优化
  • 原文地址:https://www.cnblogs.com/mikufun-hzoi-cpp/p/12098738.html
Copyright © 2011-2022 走看看