yang-xi-jie-mi-acam

详细揭秘 ACAM

首先明确 ACAM 处理的是多模式串单文本串问题。

先对所有模式串建 trie。然后对于每个点 \(u\) 维护 \(fail_u\) 指针指向 trie 中最长的且是 \(u\) 的后缀的节点。

对于模式串为 heherssheihis 建出的 ACAM 如下

和 KMP 类似地,我们在匹配文本串时如果下一个字符没有对应的转移边,我们需要通过跳 \(fail\) 来找下一个节点。(类似 \(nxt\)

例如文本串为 shers,我们跑到节点 \(9\) 后没有找到 r 的边,那么跳 \(fail\) 后就可以找到 r 边。

也就是说,走到结点 \(9\) 后如果想要找 r 的转移应当不断跳 fail 链直到找到 r 边。

那么我们为了简化代码,我们直接将 \(9\) 节点的 r 转移边指向 \(3\)

最后建出的 ACAM 如下。黑色是为了代码好写而新加的边。

现在你学会 ACAM 加强版 了。可是 ACAM 二次加强版 每次暴力跳 fail 会 TLE。

考虑文本串每个前缀分别跳 fail 得到的节点,这些点就是在文本串中出现过的字符串。

我们把这些点打上标记,那么最后每个模式串的答案就是所在节点的标记数量。

现在我们要支持 fail 树上的到根路径加,单点查询。这个可以用数据结构维护,但是也有更方便的办法:

把每个文本串节点打上 tag,最后 pushup 统计模式串节点的 fail 子树内有多少 tag(因为每个 tag 向上爬到根都会经过这个模式串节点)。

posted @ 2024-03-07 07:44  iorit  阅读(13)  评论(0)    收藏  举报