回文自动机

概念

回文自动机,PAM,又叫回文树。

用于处理和回文子串有关的问题,和 SAM 有一些类似的地方。

构造

首先 PAM 上的每个结点代表原串的一个回文子串。

根据神秘结论,原串本质不同的回文子串至多有 n 个,也就是 PAM 的点数至多是 n+2,边数至多是 n.

考虑到回文串的奇偶性会导致一些讨论,考虑给奇数长度和偶数长度的回文子串分别构造奇根和偶根。

指针全部指向奇根,奇根长度为 1.

这样出现新字符的时候就可以直接挂到奇根。

然后考虑 PAM 上的转移。

从上到下的转移意味着在父结点代表的串中首尾各加上指定的字符。

从下到上的转移 fail 意味着该结点的最长回文真后缀对应的结点。

构造和 SAM 一样考虑增量,每次向上找到最后一个可以和当前位置匹配的结点转移就行。

向上跳相当于消耗已有的势能,势能分析得构造 PAM 的时间复杂度是 O(n).

有时候会需要知道某串中长度小于一半的回文子串,可以另外维护一个指针指向对应的子串。更新暴力向上跳就行。

套路

本质不同回文子串个数

等价于 PAM 的总点数 - 2,也就是除去奇根和偶根。

回文子串出现次数

例题:P3649 [APIO2014] 回文串

类似 SAM,考虑在回文树上求子树和。

回文树上 dp

例题:P4762 [CERC2014]Virus synthesis

考虑令 f[i] 表示构造回文树上结点 i 对应子串需要的最少次数,trans[i] 表示结点 i 长度不超过一半的最长回文真后缀结点。

讨论一下树边的转移和 trans 有关的转移就行。

k 阶回文子串计数

例题:CF835D Palindromic characteristics

考虑讨论 itrans[i] 的长度转移。

偶回文子串划分

对于给定的字符串,考虑将其划分成若干个长度为偶数的回文子串,求方案总数。

考虑朴素的 dp,令 f[i] 为前缀 [1,i] 的方案总数,则 f[i]=j=1,2iji1w(j+1,i)f[j],其中 w(l,r) 表示 S[l,r] 是否是回文串。

这个东西上树等价于从 lst 开始跳 fail,但是当回文树深度够大的时候就会 T,考虑优化。

  • 引理:任意字符串的 border 按照长度排序后可以划分成 O(log) 个等差数列。

  • 结论:若字符串 S 的某一后缀是回文的,则其必定是 S 的 border.

于是我们知道字符串的回文后缀可以划分成至多 O(log) 个等差数列。

于是我们只需要考虑在 PAM 上新加入一个结点时,其所在的等差数列产生的新贡献。

容易发现此时只会新增加 ilen(x)δ 位置的贡献,其中 i 是当前下标,len(x),δ 分别是上一个等差数列的末项和当前的公差,也就是说 len(x)+δ 为当前等差数列的首项。

于是在维护 PAM 的时候一起维护上一个等差数列的末项对应的结点就行。

时间复杂度 O(|S|log|S|).

例题:

  • CF932G Palindrome Partition

  • CF906E Reverses

posted @   kymru  阅读(103)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩