这是一篇总结,所以不会讲什么细节。
以后可能会补上细节。可以参考这几位大佬的博客:后缀数组学习笔记 、后缀数组:原理和实现,以及集训队爷的论文:后缀数组——处理字符串的有力工具 、后缀数组 。
模板
模板完全参照刘汝佳的蓝书,采用的是倍增的思想。D3算法写不来
有几处需要注意的地方在下面说明
几处说明:
1.第17行,有大佬说这么操作会打乱基数排序的特性,实际操作时貌似并无大碍。
2.第27行,有大佬说+k的时候会爆空间。jiry_2大佬反驳说并不会,因为在越界的时候本身条件就不可能成立,跳过判断了。
3.一定不要忘记在字符串尾加上一个值,否则gg(我被这里RE了无数次)。白书上有强调(“$”字符)。具体表现为向两个函数传参时的n+1
就是这么多,简而言之,这是一份大家都说有问题的,但实际跑起来没有一点事的模板。
扩展
后缀数组如果只有一个SA那也没什么大作用,这时候引入两个辅助数组:height[]和rank[]。其中,\(height[i] = LCP(sa[i - 1], sa[i])\) ,rank为名次数组,和sa两数组互为反函数,即:\(rank[sa[i]] = i\) 。(SA数组:SA[名次]=地址,RANK数组:RANK[地址]=名次)
我们令\(h[i] = height[rank[i]]\), 足以发现一个性质:\(h[i] \ge h[i - 1] - 1\)。证明是显然的。
注意,这里的i是以在数组中的地址递增的,而不要想当然地以为是按照排序好的名次递增的。
LCP还有一种基于哈希值的算法。刘汝佳没有很详细的介绍,但从他的语气中,我们可以感觉到这个算法十分的exciting。
题目
按照惯例,上模板题:
1.UOJ#35
最裸的模板题,考后缀数组和LCP,用上面给的模板就能过。但是仍能RE一些弱鸡比如我
2.BZOJ1031
也是很裸的后缀数组的题目。看起来很叼的样子,其实考你是否背熟了模板。
后话
其实很多OI选手,对于后缀数组都是背诵流。真正理解精髓的不多。
是的,我也不理解精髓。
函数Build勉强读懂前面的部分,从27行那一坨就看的犯傻,问了问群里的大佬,大佬们告诉我这是在去重排序。
这告诉我们了什么?告诉了我们还是背诵流省事
以后有时间要回头磨透= = 别人的板子永远都是别人的,默写下来出问题的时候自己都不知道自己写了什么。
xD.