博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3649 [APIO2014]回文串
阅读量:6227 次
发布时间:2019-06-21

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

思路

回文自动机

回文自动机的fail[i]就是编号为i的这个字符串的最长的回文后缀的编号,然后len[i]表示编号为i的回文串的长度,cnt[i]表示编号为i的回文串的出现次数

然后trans边就是同时在两边加上一个字符,fail边就是跳fail
然后初始有一个0节点,len为0,fail[0]=1,s[0]=-1,表示长度为2的回文串(s[i-1]和s[i]),另一个1节点,len=-1,表示长度为1的回文串(s[i]自身)
然后跳fail就是比较s[i-len[p]-1]==s[i],满足证明找到了,否则继续往上跳
然后子节点的fail就是它父亲的fail的对应转移边(类似AC自动机
然后就没有了

代码

#include 
#include
#include
using namespace std;const int MAXN = 300010;int len[MAXN],cnt[MAXN],fail[MAXN],trans[MAXN][26],s[MAXN],Nodecnt,last,n;char S[MAXN];long long ans=0;int New_state(int _len){ len[Nodecnt]=_len; return Nodecnt++;}int get_fail(int p,int n){ while(s[n-len[p]-1]!=s[n]) p=fail[p]; return p;}void add_len(int n){ int cur=get_fail(last,n); if(!trans[cur][s[n]]){ int t=New_state(len[cur]+2); fail[t]=trans[get_fail(fail[cur],n)][s[n]]; trans[cur][s[n]]=t; } cnt[trans[cur][s[n]]]++; last=trans[cur][s[n]];}int main(){ s[0]=-1; New_state(0); fail[0]=1; New_state(-1); last=0; scanf("%s",S+1); n=strlen(S+1); for(int i=1;i<=n;i++){ s[i]=S[i]-'a'; add_len(i); } for(int i=Nodecnt-1;i>=0;i--) cnt[fail[i]]+=cnt[i]; for(int i=0;i

转载于:https://www.cnblogs.com/dreagonm/p/10638676.html

你可能感兴趣的文章
程序员有趣的面试智力题(转)
查看>>
练就Java24章真经—你所不知道的工厂方法
查看>>
Android 应用兼容性最佳实践 | 中文教学视频
查看>>
Servlet第三篇【request和response简介、response的常见应用】
查看>>
Mybatis第五篇【Mybatis与Spring整合】
查看>>
优雅的类写法
查看>>
ReactNative开发必备ES6知识
查看>>
基于BIGINT溢出错误的SQL注入
查看>>
Burp Suite使用介绍(二)
查看>>
魔幻特效,慢放世界,nova 3带你玩转抖音新技能
查看>>
声明式调用---Feign
查看>>
有效的沟通,如忍者的最后一击!
查看>>
从零开始搭建一个简单的基于webpack的vue开发环境
查看>>
【功能盘点】升级后的媒体处理MPS有哪些能力?
查看>>
【iOS 印象】Swift 中值类型与引用类型指北
查看>>
python-path配置问题解决
查看>>
创建使用 framework和 a静态库
查看>>
最好的Linux发行版
查看>>
利用AudioContext来实现网易云音乐的鲸鱼音效
查看>>
JS原型与原型链总结篇
查看>>