zoukankan      html  css  js  c++  java
  • 后缀自动机的应用

    零.前置:

    (1.init:)初始状态。

    (2.end:)结束状态。

    (3.E:)结束状态(end)集合。

    (4.fa(s):parent)树上(s)的父亲节点。

    (5.Reg(s):)节点(s)能达到的(end)的集合。

    (6.mx(s):)节点(s)所代表的子串的最长长度。

    (7.mn(s):)节点(s)所代表的字串的最短长度。

    (8.Right(s):)状态(s)出现的右端点集合。

    (9.ST(s):)节点(s)能到达的状态集合(点数)。

    一.后缀自动机的性质:

    (1.Right(s)subset Right(fa(s)))

    (2.mn(s) = mx(fa(s))+1)

    (3.s)所代表的所有串在母串中出现的次数和每次出现的右端点相同。

    (4.)后缀自动机的(parent)树是原串的反向前缀树(把每个前缀的反串插入到(Trie)树中,并且把没有分支的链合并)。

    二.如何求拓扑序:

    (exists e(u,v))(mx(u) < mx(v));若(fa(v)=u)也能得到(mx(u) < mx(v))。所以将节点按照(mx)数组排序,可以得到拓扑序(基排(O(n)))。

    三.如何求Right(s):

    若只求大小,可以按照逆拓扑序递推;如果还需要求具体节点,需要平衡树(启发式合并)/可持久化平衡树;如果需要动态维护(|Reg(s)|)(建立的同时维护),则需要一个数据结构,支持在有根树上加边删边,求子树和,因为有根把子树和转化成链上加减,单点查询然后(LCT)即可。

    三.如何求ST(s):

    逆拓扑序递推,若求本质不同,则每个状态贡献1;若相同算多次,则每个状态贡献(|Right|)次。

    其他应用:

    (1.)求本质不同子串数量:(sum_{s}mx(s) - mn(s) + 1)

    (2.)求字符串的最小表示:先对(S+S)建立(SAM),然后在(SAM)上跑,每次贪心走字典序最小的出边,走(|S|)步即可。

    (3.)求两个字符串的最长公共子串:对一个串建立(SAM),然后跑匹配,如果失配则跳(fa)

    (4.)求后缀树和后缀数组:把反串建(SAM)然后(parent)树就是后缀树,后缀树上(dfs)得到后缀数组。

    (5.)字典序(k)小子串:求(ST)然后类似线段树二分的去做。

    (6.)求本质不同的子串总长:(sum_{s}sum_{i=mn(s)}^{mx(s)}i)

    ({color{red}{ ext{咕}}}{color{green}{ ext{咕}}}{color{blue}{ ext{咕}}}{color{brown}{ ext{咕}}}{color{gold}{ ext{咕}}}{color{grey}{ ext{咕}}}{color{purple}{ ext{咕}}}{color{pink}{ ext{咕}}}{color{red}{ ext{咕}}}{color{green}{ ext{咕}}}{color{blue}{ ext{咕}}}{color{brown}{ ext{咕}}}{color{gold}{ ext{咕}}}{color{grey}{ ext{咕}}}{color{purple}{ ext{咕}}}{color{pink}{ ext{咕}}})

  • 相关阅读:
    JDBC之一:JDBC快速入门
    AdapterView及其子类之四:基于ListView及SimpleAdapter实现列表
    AdapterView及其子类之三:基于ListView及ArrayAdapter实现列表
    AdapterView及其子类之二:使用ListActivity及ArrayAdapter创建列表
    AdapterView及其子类之一:基本原理(ListView、ListActivity类型)
    Fragment之一:基本原理
    Loader之二:CursorLoader基本实例
    Intent 跳转Activity
    Android 第三课 构建简单的用户界面
    android第二课:运行你的应用
  • 原文地址:https://www.cnblogs.com/Smeow/p/10698378.html
Copyright © 2011-2022 走看看