首先显然往 KMP 想,但是好像没有限制总长诶那怎么办呢(
考虑把 (x,c) 这个二元组看做一个字符。
求 Fail 的时候除了第一个二元组,别的二元组都要完全匹配。
因为如果仅是 c 相同而 x 不同,下一个字符一定匹配不上,没有什么用。
但是答案是需要这些贡献的。所以一个 Fail 应当造成一个等差数列的贡献。
诶但是有可持久化怎么办呢(
建个操作树递归处理(在线模拟这个也是可以的,只不过要把操作树上的链可持久化下来)。
诶但是 KMP 复杂度不是均摊的吗怎么办呢(
众所周知 AC 自动机暴力跳 Fail 复杂度是错的,所以我们的做法是直接把失配的边连向失配之后该跳到的状态。
KMP 也可以类似这样做,我们就得到了一个叫 KMP 自动机的东西。
然后主席树维护一下边和贡献就可以了(
具体地,注意到对于 i≤x 都有一个 li+i 的形式,其中 li 是 Fail 链上在此处深度最大的贡献。
i 拆出来直接算,li 可以用主席树区间赋值维护。
代码:
1 |
|