回文自动机

板子略过。

和 $ SAM $ 不一样,$ PAM $ 的转移边构成的图也是一棵树。

转移边定义:若 $ x $ 到 $ y $ 有一条边权为 $ c $ 的转移边,则表示 $ y = c + x + c $。

后缀链接定义:对于一个结点 $ u $ 的后缀链接 $ fa \(,\) fa $ 是 $ u $ 结点所表示的子串的最长回文后缀。

然后做题就是考虑这两个东西的性质就行了。

P3649 [APIO2014] 回文串

考虑出现次数怎么求。

每加入一个点,给这个点到根的所有点的 $ siz $ 都加一。

最后直接统计每个结点的 $ siz $ 乘以 $ len $ 即可。

我在思考一个问题,为什么只能从 $ fail $ 树上去进行统计,不能从转移树上去统计?

我去我懂了。

你现在要加上的是,在整个串加入之后多出来的贡献。

然后多出来的肯定是包含最后一个字符也就是所有后缀回文的贡献。

所以只能跳 $ fail $ 树!!!

HDU - 5421 Victor and String

要支持从头尾插入。

和板子其实一样,直接维护一个从前开始插入的 $ lst $ 和从后开始的 $ lst $ 指针即可。

考虑事实上只有一种情况这两个指针会互相影响,即整个串都是回文串的时候,这个时候直接把两个指针放到同一个结点上即可。

死因是没开 long long /oh

loj#6070. 「2017 山东一轮集训 Day4」基因

哎你考虑一下分块,直接先预处理出以每个块开头到整个序列的结尾的答案。

这个可以直接 $ PAM $ 在 $ O(n\sqrt{n}) $ 的时间预处理出。

然后你现在需要考虑前面的这些散块的答案。

为了防止繁琐且常数巨大的清空操作,我们直接考虑不清空,求这个本质不同回文子串的答案换成对于每一个结点记录一个时间戳,检查它在本次扫描的过程中是否出现过,然后来统计答案。

前面在预处理的时候顺便预处理出,以每个块开头的每个节点第一次出现的位置,以及以每个结点开头的最长回文子串。

然后直接向前插入计算答案即可。

好像不能用均摊的 $ PAM $ /fn/fn/fn

P4762 [CERC2014] Virus synthesis

想一下,你最后一次进行操作二的时候,所得到的这个串一定要是最长的偶回文子串才是最优的对吧。

然后你的问题就转化为了给你一个串,让你求这个串的最长偶回文子串。

怎么做?

考虑 DP,在 $ PAM $ 上 DP。

对于每一个结点,找出它的最长回文子串,满足这个子串的长度小于 $ \lfloor \dfrac{len}{2} \rfloor $,记这个结点为 $ link $。

开始 DP,记 $ f_u $ 表示构成 $ u $ 这个结点所表示的字符串所需要的最小步数。

那么现在考虑对于一条转移边,$ u $ 到 $ v $。

一定有 $ f_v = f_u + 1 $,由 $ PAM $ 定义,$ v $ 所表示的字符串等于 $ u $ 所表示的字符串两边同时加一个字符,由于反正都要复制一次,所以可以直接在一边加。

还可以从 $ link $ 转移,我可以先变成 $ link $,然后暴力加到一半,然后再翻倍。

即 $ f_v = f_{link} + 1 + \frac{len_v}{2} - len_{link} $

直接 $ bfs $ 一遍就做完了。

CodeChef PALPROB Palindromeness

我去怎么是上题弱化版。

你还是预处理出那个每个结点的 $ link $。

然后如果它的 $ len_{link} \ != \lfloor \dfrac{len_u}{2} \rfloor $,那么就不加 $ len_{link} $ 的贡献,否则就加上。

然后就做完了。

posted @ 2026-02-02 20:49  LittleFoxFairy  阅读(0)  评论(0)    收藏  举报