《后缀数组——处理字符串的有力工具》

上次看这篇论文还是过年的时候,太懒了,没有把上面例题做完,今天花了一下午,终于把上面的题切完了,其实只写了几道(例8还要wa,拍了半天找不出错),其他的看出来就不想写了。

例一:裸的sa;

例二:可重叠最长重复子串,直接在height中取max就是了。

例三:不可重叠的最长重复子串:二份答案,在每一组中判断最前面与最后面的是否相交。

例四:可重叠最长k重复子串:依旧二份答案,在每一组中判断是否存在k份。

例五:不相同的子串个数:建好sa后,由1...N扫,每次增加max(0,height[i]-height[i-1])。

例六:最长回文子串:先反向搞一遍原串,揉到一起建一个sa;回文串分奇偶,枚举以每一个点或者每两个点之间为中心的回文串的长度,即他们在sa中的lcp。

例七:最多次连续重复子串:考虑如果1==2,2==3,3==4...n-1==n,那么1==2==3==4...所以枚举子串长度,对于长度L,如果lcp(S(1...N),S(L+1...N))==N-L说明该字符串可以由N/L个长度为L的子串得到。

例八:重复次数最多的连续重复子串:枚举子串长度,对于长度L,如果出现次数>=2(至少都是1嘛),则他在(0...L)(L...2L)(2L...3L)....(kl....kl+l)中至少出现一次,所以我们可以计算lcp(S(iL...N),S(iL+L...N))来算出长为L的出现了多少次=lcp(S(iL...N)/L+1。但这还有一点问题,我们没有考虑(iL-L...iL)这段区间的影响,他可能使答案加一(也最多加一),所以我们考虑(iL-L....iL)中后(L-lcp(S(iL...N),S(iL+L...N))%L)个与(iL....iL+L)中后(L-lcp(S(iL...N),S(iL+L...N))%L)个是否相等,依旧使用sa判断,如果想等ans++;

例九:两个串的最长公共子串:连到一起建sa,在不在同一个串中取max{height[]};

例十:两个串的长度不小于k的公共子串的个数:令两个串分别为A,B。连起来建sa,分组,在每一组中看sigma{lcp()-K+1},可以用单调队列维护,因为只有两种情况:前面属于A,后面的属于B,前面的属于B,后面的属于A,他们一样的。只考虑前面属于A,后面的属于B的。维护一个递增的单调队列,记录A的每一个后缀对答案的贡献,即sigma(lcp()-K+1),后缀的个数,该后缀到此时的lcp。新加一个就把前面比他lcp大的合到一起,这样是O(N)的,总复杂度是O(Nlogn)的。

例十一:不小于k个字符串中的最长公共子串:类似于两个字符串,只是判断是否存在k个。

例十二:在每个字符串中出现不相交的两次的最长公共子串:二分长度,在每一组中记录每一个字符串出现的最早,最晚时间,看是否相交。

例十三:出现或者翻转出现在每个字符串中的最长子串:一样的题,先翻转一遍,然后就是例十二了。



感触:

1.任何子串都是某一个后缀的前缀。

2.连接,分组与二分是常用手段。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值