题意:
求目标串中每个模式串出现几次
目标串长度<=2000000 模式串<=1000个 模式串长度<=50
题解:
这不就是AC自动机的模板题吗!
求fail树中模式串的子树中有几个是目标串的节点就完了- -
但是 这样做不是太没意思了 (← ←...)
昨天晚上听说后缀数组好像可以完美替代AC自动机(事实上是不行的)
于是就拿出了这道题 思考如何用后缀数组解决
其实一想还是挺简单的
先把这些串接起来 求个sa和hi
记第i个模式串的的位置是sp[i]
显然包含模式串i的后缀在sa中肯定跟sp[i]相邻
我们只要往两个方向枚举求几个是目标串的即可
Q1:
这时时间复杂度为O(模式串个数*串总长度)=O(2*10^9)
TLE!优化?
将属于目标串的后缀赋值为1
线段树维护sa中区间连续某段的和 即可将时间复杂度缩为O(模式串个数*log串总长度)
Q2:
但是有个问题 怎么快速求出询问的区间范围?
枚举?那复杂度不是又变回去了- - 主席树!
这个区间范围就是该点左边、右边hi<该模式串的长度的第一个点
我们可以主席树logn求之
但是这个方法的bug还是很多的- -
比如说这题时限只有1s O(nlogn) 还是很艰难的
还有空间复杂度也要差不多O(nlogn) MLE毫无压力- -