「总结」后缀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\)
这样复杂度是:

\[\sum\limits_{i=1}^{n}\frac{n}{i}=nln n \]

posted @ 2019-12-25 14:43  Lrefrain  阅读(180)  评论(0编辑  收藏  举报