gggyt  
没谁离不开谁

  用途:(a)可以在某一字符串中搜索另一字符串的所有出现位置

      (b)计算不同子串的个数

  线性时间内解决字符串问题

  后缀自动机最重要的性质是:它包含了一个字符串所有的字串信息。

  后缀自动机是一张有向无环图,边表示状态

  一个串的子串有多少之类的问题,或是询问子串/后缀的问题,就用子边转移(自动机性质)。

 

  而计算一个串重复出现次数(right集合的问题),回退到最长匹配状态(LCS问题),就用父边转移(后缀树性质)。

 

  endpos(结束位置)

  定义a. 两个非空子串u和v(length(u)<=length(v))是终点等价的,当且仅当u在字符串s中仅作为w的后缀出现。

  后缀自动机的应用:

    

    存在性查询 
    问题:给定文本T,询问格式如下:给定字符串P,问P是否是T的子串。 
    算法:我们对文本T用O(length(T))建立后缀自动机。 
    解释:从s状态开始走,沿着串p的字符开始走,如果能够走通则是子串,否则不是

 

    不同子串个数 
    问题:给定字符串S,问它有多少不同的子串。 
    算法:构建S后缀自动机,O(n) 
    解释:S的任意子串都对应SAM中的一条路径,所以路径条数就是子串个数

 

    不同子串的总长 
    问题:给定字符串S,求其所有不同子串的总长度。 
    算法:上题类似,加个长度

 

    字典序第k小子串 
    问题:给定字符串S,一系列询问——给出整数K_i,计算S的所有子串排序后的第K_i个。 
    复杂度要求:单次询问O(length(ans)*Alphabet),其中ans是该询问的答案,Alphabet是字母表大小。 
    算法:这一问题的基础思路和上两题类似。字典序第k小子串——自动机中字典序第k小的路径。因此,考虑从每个状态出发的不同路径数,我们将得以轻松地确定第k小路径,从初始状态开始逐位确定答案。

 

    最小循环移位 
    问题.给定字符串S,找到和它循环同构的字典序最小字符串。

 

    出现次数查询 
    问题.给定文本T,询问格式如下:给定字符串P,希望找出P作为子串在文本T中出现了多少次(出现区间可以相交)。

 

    首次出现位置查询 
    问题.给定文本T,询问格式如下:给定字符串P,求P在文本中第一次出现的位置。

 

    所有出现位置查询 
    问题.给定文本T,询问格式如下:给定字符串P,要求给出P在T中的所有出现位置(出现区间可以相交)。

 

    查询不在文本中出现的最短字符串 
    问题.给定字符串S和字母表。要求找出一个长度最短的字符串,使得它不是S的子串。

 

    求两个字符串的最长公共子串 √
    问题.给定两个字符串S和T。要求找出它们的最长公共子串,即一个字符串X,它同时是S和T的子串。

 

    多个字符串的最长公共子串 
    问题.给出K个字符串S_1~S_K。要求找出它们的最长公共子串,即一个字符串X,它是所有S_i的子串。

 

posted on 2017-09-12 18:28  gggyt  阅读(440)  评论(0编辑  收藏  举报