后缀数组的简单自用定理和技巧自用
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[])数组。
2.对于后缀数组快速求两个子串的(lcp)
前置,两个子串的(lcp)为它们之前所有(H[])的最小值。
所以
先切好所有(H[])
放到(st)表里面一锅煮。
然后(O(nlogn))慢炖。
最后就可以愉快的(O(1))品尝了!
3.对于后缀数组求相同回文子串
用回文自动机多好
大概是利用manacher处理出本质不同的回文串
然后记录当前位置,就可以利用(rmq+H[])查到有多少个(H[])长度与这个回文子串相同的其它回文子串了。
4.对于后缀数组求本质不同的子串
这大概是一个公式qwq
(n*(n-1)/2-sum_{i=1}^{n}H[i])
这大概就是先把所有的相同子串默认都是本质不同的
然后因为对于(H[i]),有一段子串是相同的,这意味着我们多算了一遍,把它减去就可以了。
5.对于后缀数组求环的sa排序
断环成链倍增咯。
某些情况下不能直接加上去,可以在后面加上一个没有出现过的字符。
这种方法可以用来处理掉两个子串求相同子串等问题吧。
6.关于一些后缀数组的练习题?
[TJOI2017]DNA
[NOI2015]品酒大会
[NOI2016]优秀的拆分
[USACO07DEC]最佳牛线,黄金Best Cow Line, Gold
[HAOI2016]找相同字符
[SCOI2012]喵星球上的点名