Loading

CF1097H Mateusz and an Infinite Sequence

这种模非常小的数意义下的递归结构的区间查询显然可以抽象为 \(O(d\log_{d} V)\) 次信息的合并,问题的关键在于如何快速的处理信息的合并。

一个非常 \(\text{trival}\) 的想法是每次合并时直接计算跨过分界点的区间个数,但这个严格不弱于通配符匹配问题,直接使用卷积只能做到 \(O(nm^2d\log_{d} V+nmd\log n\log_{d}V)\),是非常劣的。但是实际上一个区间的长度如果 \(\geqslant n\),那么这个区间的前后缀的匹配信息是不会变动的,可以直接继承上去,那么我们只需要计算无法继承的区间即可。

不难发现其实类似线段树,实际上定位到的满足自身 \(\geqslant n\) 且子结点都 \(<n\) 的区间个数至多只有两个,但这个区间的长度是可以达到 \(O(nd)\) 级别的,这样只能做到 \(O(nm^2d+nmd+nmd\log_{d}V)\),但 \(\text{NTT}\) 常数很大,还是不太行。

实际上虽然该问题的一般形式强于通配符匹配问题,但是由于其有递归结构,可以将通配符匹配本身也看作一个递归的信息合并,在不仅记录前后缀信息匹配的同时把通配符匹配也作为一个信息计入状态。这个看起来其实很不协调,实际上是将其进行了一个数据分治,当一个区间长度小的时候将其全部的匹配状态记录下来是可以的,当一个区间长度很大的时候只用记录前后缀就可以了。这样我们甚至将普通的递归结构字符串匹配问题扩展到了通配符匹配问题,这样可以 \(O(nmd\log_{d}V)\),但复杂度依然很高。

上述过程存的均为 \(01\) 变量,可以将其压成一个 \(\text{bitset}\),但由于 \(\text{bitset}\) 库函数不能 \(\text{reverse}\),在存的时候可以将后缀与通配符匹配信息同时翻转,这样相应的位就对齐了,于是可以做到 \(O(\frac{nmd\log_{d}V}{w})\)。对于单组询问的普通的递归结构字符串匹配问题,无需处理 \(\text{kmp}\) 自动机的倍增结果。

posted @ 2024-04-09 20:43  zhouhuanyi  阅读(34)  评论(0编辑  收藏  举报