zoukankan      html  css  js  c++  java
  • 后缀自动机学习笔记

    主要由两部分组成,一个图和一颗trie树

    图上从根出发的每一条路径代表了原图的一个子串,树是原串子串的倒序形成的字典树

    关于构造是用的增量构造

    考虑已经建好了一个后缀自动机,如果在字符串末尾增加一个字符,会对自动机有什么影响

    首先全字符串肯定是第一次出现,所以要从前一个添加的字符处向当前字符连边,构造出对应全串的一条路径

    之后对于以当前字符结尾的长度渐短的字符串,如果是第一次出现,那么便归属当前字符管辖,当第一次发现之前出现过这个字符串时,就代表之后的所有字符串也已经出现过了,因为后面的字符串都是已经出现过串的后缀,所以这一部分的字符串就交予之前出现的地方管辖。意思就是说,从根出发已经可以走出这种路径,就不必因为新加入点而改变什么了。仔细想想,因为字典树是插入的原串子串的倒序,所以这个串出现和之前重复的情况时,重复串必然在字典树中是当前串的父节点。

    所以在构造时我们加入一个点,就从之前添加的最后一个点往上找他的父亲节点,如果这个节点没有一个到当前字符的转移,那么添加一条转移边,如果存在一条转移边到当前字符就说明在之前就已经出现过了这个子串。

    然后我们就会发现一个现象,一个新的串要加入trie树,但是我们之前为了保证复杂度是把串缩成点的,这时要插入就难免违背trie的性质,这个时候我们就要把上面的点拆开,拆出一个最长公共前缀,而这个前缀我们实际上已经求出,就是字符串重复出现时的位置,那么我们要拆出的长度其实是重复位置的节点所掌管的长度加1。特殊的,如果我们重复点掌管长度加1就等于我们要加入的点的父节点的管辖长度就可以不用拆点,因为其是完全满足字典树关系的,就像缩点后父节点的代表串为AB,我们要插入ABA自然可以直接插入其下,但要插入AC就必须把AB拆掉。

  • 相关阅读:
    [算法] 归并排序(自顶向下、自底向上)
    [算法] 快速排序(单路、双路、三路)
    [算法] O(nlogn)和O(n^2)算法性能比较
    [算法] O(n^2)算法的效率比较
    [设计模式] 设计模式课程(十九)--职责链模式
    [OS] 汇编语言
    [c++] 内存模型
    [c++] 内存与变量
    [Qt] 基本概念
    42. Trapping Rain Water
  • 原文地址:https://www.cnblogs.com/ihopenot/p/5916888.html
Copyright © 2011-2022 走看看