回文自动机学习小记

来源:互联网 发布:赛诺手机数据是啥 编辑:程序博客网 时间:2024/06/07 23:31

前言

比manacher多了许多功能。
作为自动机,它能够识别所有回文子串。

构造

类似后缀自动机、AC自动机一样,回文自动机也有fail指针。
而且,回文自动机是一种每次往两端加字符的神奇trie(不知所措)。
对于自动机内一点所代表的回文串,其fail指针指向的点所代表的回文串是该回文串的最长回文后缀。
首先有两个根节点0和1,0代表空,1代表一种神奇的字符叫做被吞了一个(奥妙重重),用len表示一个结点所代表的回文串的长度,那么len[1]=-1(等会再解释,先上车)。pre[0]=1,pre[1]=1。
首先类似后缀自动机有一个last,每次在原串s后插入一个新字符ch,都从last出发,不断沿pre跳,直至找到一个x满足s[i-len[x]-1]=s[i],那么得到新的回文串,我们看x有没有ch儿子,没有就新建一个,对新建结点当然也要找到其pre,只要再从x出发往上找合法点即可(从x开始跳这里不包括x,也可以理解为从pre[x]开始跳)。可以证明,找到的这个合法点一定存在ch儿子。
不管有没有新建点,最后x的ch儿子size(或称之为cnt,反正就是表示这个回文串的出现次数)加一。
最后倒推size[pre[i]]+=size[i]即可。
然后我们发现,len[1]=-1恰到好处。s[i-(-1)-1]=s[i],相当于新增加了一个单个字符回文串。
还有注意,pre不能连向1,但由于初始空儿子设为0,那么不用进行特判。
例题:[APIO2014][jzoj3654]回文串,[JSOI2013][jzoj3291]快乐的JYY。

0 0
原创粉丝点击