省选算法学习-回文自动机 && 回文树
前置知识
首先你得会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];
}
}
省选算法学习-回文自动机 && 回文树的更多相关文章
- Palindromic Tree 回文自动机-回文树 例题+讲解
回文树,也叫回文自动机,是2014年被西伯利亚民族发明的,其功能如下: 1.求前缀字符串中的本质不同的回文串种类 2.求每个本质不同回文串的个数 3.以下标i为结尾的回文串个数/种类 4.每个本质不同 ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- 省选算法学习-数据结构-splay
于是乎,在丧心病狂的noip2017结束之后,我们很快就要迎来更加丧心病狂的省选了-_-|| 所以从写完上一篇博客开始到现在我一直深陷数据结构和网络流的漩涡不能自拔 今天终于想起来写博客(只是懒吧.. ...
- 省选算法学习-插头dp
插头dp?你说的是这个吗? 好吧显然不是...... 所谓插头dp,实际上是“基于连通性的状态压缩dp”的简称,最先出现在cdq的论文里面 本篇博客致力于通过几道小小的例题(大部分都比较浅显)来介绍一 ...
- 省选算法学习-BSGS与exBSGS与二次剩余
前置知识 扩展欧几里得,快速幂 都是很基础的东西 扩展欧几里得 说实话这个东西我学了好几遍都没有懂,最近终于搞明白,可以考场现推了,故放到这里来加深印象 翡蜀定理 方程$ax+by=gcd(a,b)$ ...
- 省选算法学习-dp优化-四边形不等式
嗯......四边形不等式的确长得像个四边形[雾] 我们在dp中,经常见到这样一类状态以及转移方程: 设$dp\left[i\right]\left[j\right]$表示闭区间$\left[i,j\ ...
- 算法学习——从bzoj2286开始的虚树学习生活
[原创]转载请标明原作者~ http://www.cnblogs.com/Acheing/ 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2 ...
- 【算法学习】【洛谷】树链剖分 & P3384 【模板】树链剖分 P2146 软件包管理器
刚学的好玩算法,AC2题,非常开心. 其实很早就有教过,以前以为很难就没有学,现在发现其实很简单也很有用. 更重要的是我很好调试,两题都是几乎一遍过的. 介绍树链剖分前,先确保已经学会以下基本技巧: ...
- 数据结构和算法学习笔记十五:多路查找树(B树)
一.概念 1.多路查找树(multi-way search tree):所谓多路,即是指每个节点中存储的数据可以是多个,每个节点的子节点数也可以多于两个.使用多路查找树的意义在于有效降低树的深度,从而 ...
随机推荐
- SQL递归查询实现组织机构树
系统用到的组织机构树,要实现对当前节点以及其子节点的查询,数据库SQL要用到递归查询,这也是我第一次接触SQL的递归查询. 先说一下什么是递归查询,简单说来是将一个树状结构存储在一张表里,比如一个表中 ...
- Linux apt & yum 及 常用命令
yum yum 语法 yum [options] [command] [package ...] options:可选,选项包括-h(帮助),-y(当安装过程提示选择全部为"yes" ...
- spring框架中@PostConstruct的实现原理
在spring项目经常遇到@PostConstruct注解,首先介绍一下它的用途: 被注解的方法,在对象加载完依赖注入后执行. 此注解是在Java EE5规范中加入的,在Servlet生命周期中有一定 ...
- Laravel5.5.x集成Swagger (L5-Swagger) 只讲Laravel5.5.x的集成,laravel其他版本请自行研究或参考github上的说明
--------上图 截取自Github 官网上的安装参考----------------------------------------------------------------------- ...
- MySQL的隐式类型转换整理总结
当我们对不同类型的值进行比较的时候,为了使得这些数值「可比较」(也可以称为类型的兼容性),MySQL会做一些隐式转化(Implicit type conversion). 比如下面的例子: 1 2 ...
- POJ:1258-Agri-Net
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65322 Accepted: 27029 Descriptio ...
- パラメータID一覧
名称 内容 ABK 処理グループ. AUF 受注伝票タイプ. AVE FI:支払明細通知書のテンプレート登録. BAR 伝票タイプ. BNK 銀行コード. BUK 会社コード. CAC 管理領域. D ...
- Spark&Hive结合起来
1.spark与Hive结合起来 前提:当你spark的版本是1.6.1的时候,你的Hive版本要1.2.1,用别的版本会有问题 我们在做的时候,Hive的版本很简单,我们只需要解压缩,告诉他Hive ...
- vue命令集合
创建vuecli脚手架:npm install -g @vue/cli拉取2的版本:npm install -g @vue/cli-init 创建webpack:npm i webpack@3.12. ...
- DOM事件里封装方法eventUtil
var eventUtil={ //添加句柄 addHandler:function (element,type,handler) { //element相当于btn2,type此时用的是click类 ...