博客
关于我
回文自动机
阅读量:286 次
发布时间:2019-03-03

本文共 1024 字,大约阅读时间需要 3 分钟。

【算法介绍】

这个一个长得很像AC自动机的自动机回文自动机(PAM)

对于每个点仍然是由转移边,表示每个点的位置向左右各延伸一个字符c,形成的回文串

考虑fail边记录什么,我们主要利用fail去进行加速查找,所以有用的信息是每个位置的最长回文后缀

fail记录每个串的最长回文后缀的左端点,len记录当前位置的回文串长度

设立两个起始节点,0和1,0表示长度为偶数的串的开始,1表示长度为奇数的开始

所以注意赋初值:len[1]=-1 fail[0]=1 tot=1

【例题1】

P5496 【模板】回文自动机(PAM)

【题意】

给定一个字符串 s。保证每个字符为小写字母。对于 s 的每个位置,请求出以该位置结尾的回文子串个数。强制在线

【分析】

直接建立回文自动机

然后考虑每个位置结尾的回文子串个数就是沿着fail的深度,直接转移的时候维护一个sum即可

【代码】

#include
using namespace std;const int maxn=5e5+5;char s[maxn];int tr[maxn][26],len[maxn],cur,tot,last,fail[maxn];int sum[maxn];int getfail(int x,int i){ while(i-len[x]-1<0 || s[i-len[x]-1]!=s[i]) x=fail[x]; return x;}int main(){ freopen("a.in","r",stdin); scanf("%s",s); int l=strlen(s); fail[0]=1; len[1]=-1; tot=1; for(int i=0;i
=1) s[i]=(s[i]+last-97)%26+97; int pos=getfail(cur,i); if(!tr[pos][s[i]-'a']) { fail[++tot]=tr[getfail(fail[pos],i)][s[i]-'a']; tr[pos][s[i]-'a']=tot; len[tot]=len[pos]+2; sum[tot]=sum[fail[tot]]+1; } cur=tr[pos][s[i]-'a']; last=sum[cur]; printf("%d ",last); } return 0;}

 

转载地址:http://bpwm.baihongyu.com/

你可能感兴趣的文章
PHP基础-变量的作用范围
查看>>
PHP基础-类的静态变量的读取
查看>>
PHP7.0--如何使用函数的引用
查看>>
天干地支年份算法的猜想(虾米大王)
查看>>
Java基础--01--数据类型/方法/数组
查看>>
【JokerのZYNQ7020】LINUX_EMIO_LED。
查看>>
【JokerのZYNQ7020】LINUX_EMIO_BUTTON。
查看>>
将代码从windows移动linux上出现^M错误的解决方法
查看>>
AC自动机的使用案例
查看>>
git查看相对于最新的push改动内容
查看>>
vim匹配特定的行并删除
查看>>
读取excel文件错误
查看>>
傅里叶变换的初级理解三
查看>>
伟大的欧拉公式
查看>>
F1 score的意义
查看>>
画多个图及相关细节总结
查看>>
python36+centos7离线安装tensorflow与talib的方法
查看>>
金融数据信噪比的影响力又一力证
查看>>
hdf5与hdfs的区别
查看>>
scala运行的方式
查看>>