后缀数组自用

后缀数组的简单自用定理和技巧自用

1.对于H[]数组的定义

前置:
(lcp(x,y))表示字符串(x)(y)最长公共前缀。
(height[i])(lcp(sa[i],sa[i-1]))
(H[i])(height[rak[i]]),表示当前位置与前一个排名的最长公共前缀。
那么显然(H[i]>=H[i-1]-1)
因为(H[i-1])可以保证的是(i-1)后面也许会有一个后缀是(i-1)的前缀。
要不就是0;
可以想到既然(i-1)(i)只相差一位,那么是不是那个属于(i-1)的前缀的在后面出现的后缀,再推后一位就是第i位的前缀了呢?

Ps:(rak[i])为当前i位置后缀的排名。

作用:可以(O(n))快速求出(H[])数组。

例题:# [USACO06DEC]牛奶模式

2.对于后缀数组快速求两个子串的(lcp)

前置,两个子串的(lcp)为它们之前所有(H[])的最小值。
所以
先切好所有(H[])
放到(st)表里面一锅煮。
然后(O(nlogn))慢炖。
最后就可以愉快的(O(1))品尝了!

3.对于后缀数组求相同回文子串

用回文自动机多好

大概是利用manacher处理出本质不同的回文串
然后记录当前位置,就可以利用(rmq+H[])查到有多少个(H[])长度与这个回文子串相同的其它回文子串了。

[APIO2014]回文串

4.对于后缀数组求本质不同的子串

这大概是一个公式qwq

(n*(n-1)/2-sum_{i=1}^{n}H[i])

这大概就是先把所有的相同子串默认都是本质不同的
然后因为对于(H[i]),有一段子串是相同的,这意味着我们多算了一遍,把它减去就可以了。

不同子串个数

5.对于后缀数组求环的sa排序

断环成链倍增咯。
某些情况下不能直接加上去,可以在后面加上一个没有出现过的字符。
这种方法可以用来处理掉两个子串求相同子串等问题吧。

[JSOI2007]字符加密

6.关于一些后缀数组的练习题?

[TJOI2017]DNA
[NOI2015]品酒大会
[NOI2016]优秀的拆分
[USACO07DEC]最佳牛线,黄金Best Cow Line, Gold
[HAOI2016]找相同字符
[SCOI2012]喵星球上的点名

原文地址:https://www.cnblogs.com/hhh1109/p/10486354.html