回文自动机 PAM
回文自动机 PAM
约定字符串下标从
定义
回文自动机,又称回文树,是一种 2014 年才发表的新算法。顾名思义,回文自动机用于求解回文串问题。它相较于 Manacher 算法的优点在于支持在线修改且复杂度不变。
实现
回文自动机的关键技术可以概括为 “奇偶字典树 + 后缀链跳跃”。
后缀链跳跃
考虑如何设计一种高效的求回文串的算法。Manacher 采用了递推,从
说了这么多,我们应当试图从
这个操作,就是后缀链跳跃。
奇偶字典树
类似于 AC 自动机的
字典树上的每个节点的回文串实际上是从它到根再到它这么一个串。每个点需要维护的是这个回文串的长度,以及在字典树上的父亲和儿子。
建立 PAM 是一个动态的过程,考虑到每一个节点代表的回文串一定是某一个位置为结束位置的最长回文串,所以每加入一个字符
最后,对于初始状态来说,我们让偶字典树的根的
代码(P5496 【模板】回文自动机(PAM))
#include<bits/stdc++.h>
using namespace std;
constexpr int MAXN=5e5+5;
string s;
int n,tot=1,lst;
struct PAM{
int len,fail,dep,s[26];
}p[MAXN];
// 背板!
void init(){
p[0].fail=1;
p[1].len=-1;
}
int gtf(int x,int i){
while(i-p[x].len-1<0||s[i-p[x].len-1]!=s[i]) x=p[x].fail;
return x;
}
void ins(int i){
int pos=gtf(lst,i),ch=s[i]-'a';
if(!p[pos].s[ch]){
p[++tot].fail=p[gtf(p[pos].fail,i)].s[ch];
p[tot].len=p[pos].len+2;
p[tot].dep=p[p[tot].fail].dep+1;
p[pos].s[ch]=tot;
}
lst=p[pos].s[ch];
}
int main(){
cin.tie(nullptr)->sync_with_stdio(0);
cin>>s;
n=s.size();
init();
for(int i=0,ans=0;i<n;i++){
s[i]=(s[i]-97+ans)%26+97;
ins(i);
cout<<(ans=p[lst].dep)<<' ';
}
cout<<'\n';
return 0;
}
复杂度
回文自动机中最耗时的操作是跳
应用
结尾回文串个数
题意:给出一个字符串
,求以每个位置为结尾的回文串个数。
注意到我们上面维护的
所以每插入一个字符输出 p[lst].dep
即可。
双倍回文子串
题意:求一个字符串的最长双倍回文子串长度。
所谓双倍回文,指的是由两个回文串拼起来得到的串,不同题目里的定义各略有不同。
典型例题:P4287 [SHOI2011] 双倍回文,[HDU6599] I Love Palindrome String。
我们已经有了一个
求
int gtf(int x,int i){
while(i-p[x].len-1<0||s[i-p[x].len-1]!=s[i]) x=p[x].fail;
return x;
}
int gts(int x,int i,int len){
while(x!=1&&(s[i-p[x].len-1]!=s[i]||p[x].len+2>(len+1)>>1)) x=p[x].fail;
return x;
}
void ins(int i){
int pos=gtf(lst,i),ch=s[i]-'a';
if(!p[pos].s[ch]){
p[++tot].fail=p[gtf(p[pos].fail,i)].s[ch];
p[pos].s[ch]=tot;
p[tot].len=p[pos].len+2;
p[tot].trans=p[gts(p[pos].trans,i,p[tot].len)].s[ch];
}
lst=p[pos].s[ch];
p[lst].ans++;
}
那么有了这个
另外,PAM 还可以辅助做一些 DP 问题,比如 P4762 [CERC2014] Virus synthesis。它的本质还是利用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】