zoukankan      html  css  js  c++  java
  • 后缀数组自用

    后缀数组的简单自用定理和技巧自用

    1.对于H[]数组的定义

    前置:
    (lcp(x,y))表示字符串(x)(y)最长公共前缀。
    (height[i])(lcp(sa[i],sa[i-1]))
    (H[i])(height[rak[i]]),表示当前位置与前一个排名的最长公共前缀。
    那么显然(H[i]>=H[i-1]-1)
    因为(H[i-1])可以保证的是(i-1)后面也许会有一个后缀是(i-1)的前缀。
    要不就是0;
    可以想到既然(i-1)(i)只相差一位,那么是不是那个属于(i-1)的前缀的在后面出现的后缀,再推后一位就是第i位的前缀了呢?

    Ps:(rak[i])为当前i位置后缀的排名。

    作用:可以(O(n))快速求出(H[])数组。

    例题:# [USACO06DEC]牛奶模式

    2.对于后缀数组快速求两个子串的(lcp)

    前置,两个子串的(lcp)为它们之前所有(H[])的最小值。
    所以
    先切好所有(H[])
    放到(st)表里面一锅煮。
    然后(O(nlogn))慢炖。
    最后就可以愉快的(O(1))品尝了!

    3.对于后缀数组求相同回文子串

    用回文自动机多好

    大概是利用manacher处理出本质不同的回文串
    然后记录当前位置,就可以利用(rmq+H[])查到有多少个(H[])长度与这个回文子串相同的其它回文子串了。

    [APIO2014]回文串

    4.对于后缀数组求本质不同的子串

    这大概是一个公式qwq

    (n*(n-1)/2-sum_{i=1}^{n}H[i])

    这大概就是先把所有的相同子串默认都是本质不同的
    然后因为对于(H[i]),有一段子串是相同的,这意味着我们多算了一遍,把它减去就可以了。

    不同子串个数

    5.对于后缀数组求环的sa排序

    断环成链倍增咯。
    某些情况下不能直接加上去,可以在后面加上一个没有出现过的字符。
    这种方法可以用来处理掉两个子串求相同子串等问题吧。

    [JSOI2007]字符加密

    6.关于一些后缀数组的练习题?

    [TJOI2017]DNA
    [NOI2015]品酒大会
    [NOI2016]优秀的拆分
    [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold
    [HAOI2016]找相同字符
    [SCOI2012]喵星球上的点名

  • 相关阅读:
    oracle_case when
    sql记录
    修改tomcat默认编码
    sql server_TED(透明数据加密)
    web请求过程
    freemarker 标签循环list 以及获取下标值
    鼠标操作
    窗口切换
    日历控件
    xpath定位
  • 原文地址:https://www.cnblogs.com/hhh1109/p/10486354.html
Copyright © 2011-2022 走看看