前置知识

首先你得会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. Docker迁移学习及其他

    起因: 有在一台服务器A上通过docker搭建git服务,由于某些原因需要将其迁移到另一台服务器B. 过程: 最终采用方式: 首先通过docker ps(-a) 查看目标容器,然后通过commit命令 ...

  2. Fiddler(一)

    Fiddler:学习scrapy,不只是满足于网页上爬去信息的成功乐趣,现在开始接触爬去手机信息了,不好解决,知道过程不会轻松,但自己想去尝试.QAQ 写这篇博客是基于以下的几位大神学习笔记,我只是做 ...

  3. Linux中的代码编辑器vim

    Vim的三种工作模式 命令行模式 插入模式 底行模式 Vim 的命令行模式 命令行模式是进入vim后的初始模式,在该模式下主要是使用方向键来移动光标的位置,并通过相应的命令来进行文字的编辑. 切换方法 ...

  4. 01 mysql 基础一 (进阶)

    mysql基础一 1.认识mysql与创建用户 01 Mysql简介 Mysql是最流行的关系型数据库管理系统之一,由瑞典MySQLAB公司开发,目前属于Oracle公司. MySQL是一种关联数据库 ...

  5. Python学习之编程基础

    学习Python之前首先我们要了解Python是什么? question 1:Python是什么? answer:Python是一门编程语言.(什么是编程语言?) 语言:语言是不同个体之间沟通的介质. ...

  6. 关于IAR软件的Go to Definition of功能问题的解决方法

    关于IAR软件的Go to Definition of功能问题的解决方法 首先,工程文件必须放在没有中文的路径下,如果路径里有中文应把中文该成英文 如:C:\Users\ABC\Desktop\新建文 ...

  7. 2-安装linux7

    1.操作系统简介 操作系统: 桌面操作系统 redhat fedora slackware ubuntu debian suse linux centos 服务器操作系统 linux redhat s ...

  8. Android webview 加载https网页显示空白

    http://www.2cto.com/kf/201110/108836.html 这个网址讲的不错. 设置webview支持https的方法: webView.setWebViewClient(ne ...

  9. 设置MySQL允许外网访问 费元星 feiyuanxing.com 站长

    1.修改配置文件sudo vim /etc/mysql/my.cnf把bind-address参数的值改成你的内/外网IP或0.0.0.0,或者直接注释掉这行. 2.登录数据库mysql -u roo ...

  10. DOS程序员手册(十五)

    837页 writeln('TRACING Current Buffer==='); holdup; bcbtrc(cvtbase^.curbfr); writeln; holdup ; writel ...