前置知识

首先你得会manacher,并理解manacher为什么是对的(不用理解为什么它是$O(n)$,这个大概记住就好了,不过理解了更方便做$PAM$的题)

什么是回文自动机?

回文自动机(Palindrome Automaton),是一类有限状态自动机,能识别一个字符串的所有回文子串

它可简化构建出回文树

回文自动机的构造

网上资料很多,不拿出来一步步说了,说一下数组意义、放个板子

$len[u]$表示节点$u$代表的回文串的长度

$ch[u][c]$代表在$u$的回文串两端添加字符$c$得到的新回文串节点

$fail[u]$表示节点$u$的回文串的最长的回文后缀所在的节点

char s[300010];
int n;
//这个板子里面的num表示当前节点的回文串出现了几遍
namespace pam{
int fail[300010],num[300010],len[300010],ch[300010][26],last,cnt;
inline int newnode(int w){len[++cnt]=w;return cnt;}
void init(){
s[0]=-1;cnt=-1;fail[0]=1;last=0;
newnode(0);newnode(-1);//插入两个根节点,设置fail
}
inline int getfail(int cur,int pos){
while(s[pos-len[cur]-1]!=s[pos]) cur=fail[cur];//跳fail
return cur;
}
void insert(int x){
int c=(s[x]-'a'),cur=getfail(last,x);
if(!ch[cur][c]){//新建节点
int now=newnode(len[cur]+2);
fail[now]=ch[getfail(fail[cur],x)][c];
ch[cur][c]=now;
}
num[last=ch[cur][c]]++;
}
}

几个容易写错的点:

fail初始化的时候,如果多组数据并且在newnode里面初始化信息,那么在init的时候记得把fail放到newnode后面

插入的时候函数传进去的是位置

newnode是len[cur]+2不是+1

一些拓展

节点上

首先显然可以统计这个节点的回文串出现次数

统计次数的时候还要加上$fail$树上子树内的所有节点的出现次数

对于一类回文串拥有某个和其$fail$树有关的性质的题目,可以记录一个$trans$,和跳$fail$一样跳,最后用$bfs$来做$dp$或者递推

关于求最小回文串分解

这个问题是问可以把一个字符串分解成最少多少个回文串

解决的方法:

考虑一个显然的$dp$:$dp[i]=dp[j-1]+1 (s[i...j]=palindrome)$

记录一个$anc[u]$

如果$len[u]-len[fail[u]]==len[fail[u]]-len[fail[fail[u]]]$,那么$anc[u]=anc[fail[u]]$

否则$anc[u]=u$

对于$u$的所有跳上去的$anc$集合$S$,我们发现,这个集合中的元素构成一个等差数列,相邻的两项差代表一种从当前点前面递推到当前点的回文串长度

对于每个回文树节点记录$tmp[u]=min(tmp[i-len[anc[u]],tmp[fail[u]])$,然后用这个$tmp[u]+1$来更新当前节点的$dp$,然后$u=fail[anc[u]]$往上跳,直到到达根

证明网上有论文,这里放个代码

inline void insert(int x){
int c=s[x]-'a',cur=getfail(last,x);
val[x]=1e9;
if(!ch[cur][c]){
int now=newnode(len[cur]+2);
fail[now]=ch[getfail(fail[cur],x)][c];
ch[cur][c]=now;
anc[now]=((fail[now]>1&&len[now]-len[fail[now]]==len[fail[now]]-len[fail[fail[now]]])?anc[fail[now]]:now);
}
last=ch[cur][c];
for(cur=ch[cur][c];cur>1;cur=fail[anc[cur]]){
tval[cur]=val[x-len[anc[cur]]];
tpos[cur]=x-len[anc[cur]];
if(anc[cur]!=cur&&tval[fail[cur]]<tval[cur]) tval[cur]=tval[fail[cur]],tpos[cur]=tpos[fail[cur]];
if(val[x]>tval[cur]+1) val[x]=tval[cur]+1,pos[x]=tpos[cur];
}
}

省选算法学习-回文自动机 && 回文树的更多相关文章

  1. Palindromic Tree 回文自动机-回文树 例题+讲解

    回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...

  2. manacher算法学习(求最长回文子串长度)

    Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...

  3. 省选算法学习-数据结构-splay

    于是乎,在丧心病狂的noip2017结束之后,我们很快就要迎来更加丧心病狂的省选了-_-|| 所以从写完上一篇博客开始到现在我一直深陷数据结构和网络流的漩涡不能自拔 今天终于想起来写博客(只是懒吧.. ...

  4. 省选算法学习-插头dp

    插头dp?你说的是这个吗? 好吧显然不是...... 所谓插头dp,实际上是“基于连通性的状态压缩dp”的简称,最先出现在cdq的论文里面 本篇博客致力于通过几道小小的例题(大部分都比较浅显)来介绍一 ...

  5. 省选算法学习-BSGS与exBSGS与二次剩余

    前置知识 扩展欧几里得,快速幂 都是很基础的东西 扩展欧几里得 说实话这个东西我学了好几遍都没有懂,最近终于搞明白,可以考场现推了,故放到这里来加深印象 翡蜀定理 方程$ax+by=gcd(a,b)$ ...

  6. 省选算法学习-dp优化-四边形不等式

    嗯......四边形不等式的确长得像个四边形[雾] 我们在dp中,经常见到这样一类状态以及转移方程: 设$dp\left[i\right]\left[j\right]$表示闭区间$\left[i,j\ ...

  7. 算法学习——从bzoj2286开始的虚树学习生活

    [原创]转载请标明原作者~ http://www.cnblogs.com/Acheing/ 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2 ...

  8. 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器

    刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...

  9. 数据结构和算法学习笔记十五:多路查找树(B树)

    一.概念 1.多路查找树(multi-way search tree):所谓多路,即是指每个节点中存储的数据可以是多个,每个节点的子节点数也可以多于两个.使用多路查找树的意义在于有效降低树的深度,从而 ...

随机推荐

  1. 理解css中的position属性

    理解css中的position 两种类型的定位 static类型:只有一个值position: static.position默认值 relative类型:包括三个值,这三个值会相互影响,允许你以特定 ...

  2. leetcode笔记(二)94. Binary Tree Inorder Traversal

    题目描述 (原题目链接) Given a binary tree, return the inorder traversal of its nodes' values. For example:Giv ...

  3. CCS选择器基础

    上周学习了HTML和css的一些基础,今天来夯实一下基础 选择器有: 1.标签选择器 :就是HTML 中的标签 如<p> <h1> <body>等 2.类选择器: ...

  4. zip压缩工具,unzip解压缩工具

    zip压缩工具,unzip解压缩工具=================== [root@aminglinux tmp]# yum install -y zip[root@aminglinux tmp] ...

  5. redis操作帮助类

    RedisHelper.java import redis.clients.jedis.*; import java.util.*; public class RedisHelper { privat ...

  6. 无法打开物理文件 XXX.mdf“,操作系统错误 5:”5(拒绝访问。)"的解决办法

    http://blog.csdn.net/blackfield/article/details/6550499 用T-SQL命令附加数据库时,出现如下异常信息: 无法打开物理文件 XXX.mdf&qu ...

  7. windows下使用curl.exe模拟ajax请求

    curl 是一般linux发行版中都带有的小工具,利用这个工具可以很方便的下载文件,我一般使用这个工具来查看某个页面相应的HTTP头信息,在Windows系统中我们也一样可以使用这个工具,如果不需要支 ...

  8. Azure Cloud Service - PaaS

    使用Azure Cloud Service有一段时间了,前阵子在公司内部做一个Cloud Service培训的时候就在想,能不能用一幅图把Cloud Service所涉及的概念都罗列出来.于是就有了下 ...

  9. WPF仿酷狗页面

    原文:WPF仿酷狗页面 版权声明:本文为博主原创文章,如需转载请标明转载地址 http://blog.csdn.net/u013981858 https://blog.csdn.net/u013981 ...

  10. P1336 最佳课题选择

    P1336 最佳课题选择 题目描述 Matrix67要在下个月交给老师n篇论文,论文的内容可以从m个课题中选择.由于课题数有限,Matrix67不得不重复选择一些课题.完成不同课题的论文所花的时间不同 ...