【后缀数组+单调队列】省队集训题istring

哎,oi生涯也有一年了,竟然不知道后缀数组这种牛B的东西,啊~~~

 

可能是受到了后缀树的影响(一直分不清后缀树和后缀数组),对于串的理解一直停留在KMP和扩展KMP上,现参读了罗穗骞牛的《后缀数组——处理字符串的有力工具》,狠下心来研究了一番,发现串竟然是一个如此美妙的结构。

 

简要的说一下自己对后缀数组的理解:

      定义suffix(i)为主串A1~length(A)的子串Ai~length(A)。

      我们现在对所有后缀suffix(1),suffix(2),suffix(3),......,suffix(length(A)),按字典序从小到大排序,定义sa(i)为第i小的后缀,那么此时所有后缀之间将会有很漂亮的性质,比如和sa(i)公共前缀最长的后缀将会是sa(i-1)与sa(i+1)之中的一个,关于这个性质,我们又可以继续扩展它的功能,比如求任意两个后缀的公共前缀,通过转化成RMQ可以做到NlogN的复杂度。

 

 

一般地,对于一个字符串S,和S中第k个字符,定义子串T=S(i..j)为一个关于k的识别子串,当且仅当

1i<=k<=j

2TS中只出现一次。

 

your task

    给出串S,求出所有关于i的识别子串。

 

利用后缀数组,我们可以求出每一个后缀的最长公共前缀为多少,换句话说,我们可以知道以i开头的子串只在主串中出现一次,最短可以为多少,由此便转化成了区间覆盖问题。

 

看了看考场上很多人的程序,都是非常不怕麻烦的写了线段树,问了佘兄发现还可以用单调队列优化,因为这道题满足如下性质:

1.对于我新插入的区间,如果有长度比我长的区间一定无用的;

2.对于已经从表头退出的区间,我们只需要记一个左端点的最大值即可。

 

关于后缀数组的实现,还是用倍增法比较好(加了优化的倍增法基本上接近O(N),具体可以参见罗穗骞2009年的论文)。

 

第一个后缀数组,代码蒯上来,纪念一下:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值