后缀数组,LCP(生命的形式,UVA 11107)

看了别人的代码才过的。

http://blog.csdn.net/scut_pein/article/details/19786707

果然抄别人的代码就会一点都不理解,很多细节都没注意到的。自己搞了好多发RE,TLE,WA才过。


就是char最大为127,最小为-128,而字符种类数必然大于这个值(主要是有100个各不相同的分隔符),所以需要用int形数组来保存合并后的串。

vis是用来标记串编号的,所以只要开大于100的空间就够了。。

合并后的串不但有100个长度为1000的串还有100个分隔符,所以空间至少要开100100。

是while(~scanf("%d",&N)&&N)或者while(scanf("%d",&N)==1&&N)而不是while(~scanf("%d",&N))。。。


自己没有想到解决办法,正确解法是将所有串连成一个大长串,并在串与串之间加一个从未出现过的分隔符将他们隔开,别忘了最后补个结束符。然后对这个串跑一遍后缀数组以及最长公共前缀,从而得到height数组。最后二分公共前缀的长度,然后去检查是否有超过一半的串都拥有这个长度的公共前缀。检查的方法就是寻找连续的height数组的区间,使得区间内的height值都大于公共前缀的长度,而且区间内包含的串的种类数(来自同一个串的后缀算一种)大于串的总个数的一半。再讲具体一点就是遍历一遍,维护区间长度以及区间内串的种类数,然后判断下有没有找到就好了。这类似最小值最大的问题,所以理应想到二分。为何可以这么检查呢?因为后缀数组其实就是将一个字符串的所有后缀排序,然后sa[i]就是后缀i的排名。而height[i]是第i名的后缀与第i-1名的后缀的最长公共前缀。第i名与第i-1名的后缀不一定是后缀j与后缀j-1,但是由于排名是相邻的,所以他们的前缀会非常相似。从而易得出连续的hei

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值