「总结」后缀2

1.喵星球的点名
发现这种多串匹配不用广义后缀自动机而用 后缀数组就是chishi。
所以当然是大力广义后缀自动机了。
我们找到每个模式串的节点,并将之所有父链节点的大小全部加一来方便查询。
匹配的时候直接输出匹配的末尾节点的大小,并且将之的标记+1。
最后再次扫一次父链节点,把标记全部统计出来即可。
复杂度是:(O(n^{1.5})),由于暴跳父亲。
但是这样的上界远远达不到。
甚至比后缀数组的大常数log跑的还快的多得多。

2.字符串
仍然后缀自动机暴力水过。
先翻转串。
首先对于每个节点线段树合并求出(endpos)集合。
考虑二分答案。
然后从前缀节点跳father跳到合适的(len)处。
这个过程可以直接用倍增来实现。
然后直接判断这个节点的(endpos)集合中是否含有([a,b])之间的元素就可以了。

3.yww 与字符串
这个题意思就是带限制的本质不同子串数目。
我们对于每个节点都维护一个(w)值代表他所能向左延伸的最长长度。
那么每个节点对本质不同子串的贡献就是:$$max(min(len[x],w[x])-len[fa[x]],0)$$
(mx)维护的时候要取(max),因为一定是取长度最长的那一个,也是由于所有本质相同的子串只要有一个是"好"的,那么就可以计算贡献。

4.外星联络
水的很,直接建后缀树然后暴力dfs一次输出即可。

5.跳蚤
挺难的题。
而且只能用后缀数组来做。
首先二分答案在所有本质不同子串的排名。
考虑如何check。
我们从字符串的末尾开始一个一个的向前加入字符,如果当前的字符串排名已经大于当前二分串的排名,那么此时必须切一刀。
最后只需要判断切的次数和(K)的关系就可以调整二分上下界了。
考虑为什么是对的。
假设我们是从前往后加入字符的话,需要判断的是([l,i],[l+1,i]……,[i,i])这些字符串中最大的一个是否排名大于二分的答案。
不是很好判断。
而我们如果从后向前加入字符的话,需要判断的是([i,r],[i,r-1],……,[i,i])这些字符串中字典序最大的显然是([i,r]),只需要处理这一个串的大小即可。
假设已经的到了排名。
首先考虑如何由排名得到答案。
我们对于每个后缀按位置处理出这样一个数组:(ra[i]),含义是(suffix(i))在所有本质不同子串中的排名。
这样的话得到转移方程:

[ra[sa[i]]=ra[sa[i-1]]+(n-sa[i]+1)-height[i] ]

也就是说除了(lcp)的部分,每一个位置都会产生一个本质不同子串。
这样我们完全可以线性的按照(rk)枚举后缀来求出(ra)数组。
求出后再次线性枚举,得到第一个使得(ra[sa[i]]>=K)的排名为(i)的后缀。
那么就很简单了,串的起点就是(sa[i])了,那末尾就是(n+K-ra[sa[i]])也就是串(s[sa[i],n+K-ra[sa[i]]])
那么考虑对于给定的(s[l,r])如何求出其排名。
首先找到这个串第一次(按rk来说的第一次)出现的后缀是哪个。
这个很简单,直接二分([1,rk[l]])的所有后缀即可,因为要得(rk)到尽量靠前并且(lcp(sa[mid],l)>=len)的后缀,所以具有单调性。
如果找到了这个位置就好说了,设这个后缀为(suffix(sa[x]))
这个子串的本质不同排名就是(ra[sa[x]]-(n-sa[x]+1-len))
这个就是(wzz)学长说的唯一的后缀数组可以办但是后缀自动机做不了的了。
对于模式串的任意排名,(logn)的求出串的位置。
对于任意的模式串子串,(logn)的求出串的排名。

6.股市的预测
仍然用后缀数组来做。
其实差分之后就是在找(ABA)形式的本质不同子串。
考虑枚举(A)的长度。
这样暴力来做的话复杂度是(n^2lnn)的。
但是我们考虑另外一种方法。
将模式串每(A)个分一块。
然后对于每块的起点(i)求出他和另一个位置(i+A+m)的最长前后缀长度,然后由于可以平移。
那么设(lcp+lcs=w),那么这一块作出的贡献就是:(w-A)
这样复杂度是:

[sumlimits_{i=1}^{n}frac{n}{i}=nln n ]

原文地址:https://www.cnblogs.com/Lrefrain/p/12096592.html