后缀数组资料

原文地址:http://hi.baidu.com/lewutian/item/2dccf95ff5f1500ae7c4a5a4


单独把它列出来是因为这个东西真的很神奇~~~

后缀数组经典思想:多串合并+二分答案+最优性--->可行性

例 1 :最长公共前缀
给定一个字符串,询问某两个后缀的最长公共前缀。   // 直接套用,ans=min( height[ i ] )+rmq    k<i<=j

例 2 :可重叠最长重复子串
给定一个字符串,求最长重复子串,这两个子串可以重叠。   // ans=max( hegiht[ i ] ) 0<=i<len

例 3 :不可重叠最长重复子串( pku1743 )      AC
给定一个字符串,求最长重复子串,这两个子串不能重叠。   // 二分转化为判定性问题

例 4 :可重叠的 k 次最长重复子串( pku3261 )       AC
给定一个字符串,求至少出现 k 次的最长重复子串,这 k 个子串可以重叠。   // 同上,也是二分

例 5 :不相同的子串的个数( spoj694,spoj705 )
给定一个字符串,求不相同的子串的个数。   
[解法]:
对于每一次新加进来的后缀 suffix(sa[k]), 它将产生 n-sa[k]+1 个新的前缀。但是其中有
height[k] 个是和前面的字符串的前缀是相同的。所以 suffix(sa[k]) 将 “ 贡献 ”
出 n-sa[k]+1- height[k] 个不同的子串。累加后便是原问题的答案。这个做法
的时间复杂度为 O(n) 。


例 6 :最长回文子串( ural1297 )
给定一个字符串,求最长回文子串。
[解法]:
将整个字 符串反过来写在原字符串后面,中间用一个特殊的字符隔开。这样就把问题变为 了
求这个新的字符串的某两个后缀的最长公共前缀。
eg:aabebf ---->   aabebf&fbebaa

例 7 :连续重复子串 (pku2406)             AC
给定一个字符串 L ,已知这个字符串是由某个字符串 S 重复 R 次而得到的,
求 R 的最大值。
[解法]:
做法比较简单,穷举字符串 S 的长度 k ,然后判断是否满足。判断的时候,
先看字符串 L 的长度能否被 k 整除,再看 suffix(1) 和 suffix(k+1) 的最长公共
前缀是否等于 n-k 。
hit:此题更好的是考察KMP的next
            int k=len-next[len];
            if(len%k==0) fprintf(fout,"%d\n",len/k);
            else fprintf(fout,"1\n");

例 8 :重复次数最多的连续重复子串 (spoj687,pku3693)   // 还未完成,抽时间好好做,先做SPOJ
给定一个字符串,求重复次数最多的连续重复子串。
[解法]:
先穷举长度 L ,然后求长度为 L 的子串最多能连续出现几次。首先连续出 现
1 次是肯定可以的,所以这里只考虑至少 2 次的情况。假设在原字符串中连续 出
现 2 次,记这个子字符串为 S ,那么 S 肯定包括了字符 r[0], r[L], r[L*2],
r[L*3], …… 中的某相邻的两个。所以只须看字符 r[L*i] 和 r[L*(i+1)] 往前和
往后各能匹配到多远,记这个总长度为 K ,那么这里连续出现了 K/L+1 次。最 后
看最大值是多少
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值