回文树 Palindromic Tree

回文树 Palindromic Tree


嗯。。回文树是个什么东西呢。
回文树(或者说是回文自动机)每个节点代表一个本质不同的回文串。
首先它类似字典树,每个节点有SIGMA个儿子,表示对应的字母。
其次它类似自动机,有一个fail指针,一个节点的fail指针指向这个回文串的最长回文后缀。比如说abbaabba的fail指向abba的最后一个a.
利用回文树,我们可以在线性(不太确定是线性还是\(nlogn\)?)的时间内求出所有本质不同的回文子串,以及以每个字母结尾的最长回文子串。
有一个定理,一个长度为n的串中本质不同的回文子串最多只有n个。本质不同是指子串本身不一样(长度不一样或者有字母不一样)。所以回文树最多有\(O(n)\)个节点。
由于回文的性质,回文树可以在线构造,不用像AC自动机那样必须离线构造。


BZOJ 3676
求一个串中,本质不同的回文子串,(出现的次数*长度)的最大值。

直接构造回文树对每个节点记录\(cnt[i]*len[i]\).


BZOJ 2565
求一个串的最长双回文子串,双回文子串可以分成连续的两部分,两部分都是回文串。

构造回文树,对原串统计以位置i结束的最长回文串的\(len[i]+len[i-len[i]]\)的最大值
注意要把原串正反分别搞两次。这就保证了我们对每个点只统计最长回文串就可以。
因为一个最长的双回文子串要么前一半是最长的,要么后一半是最长的,否则可以变得更长。


BZOJ 2160
对所有的偶回文串,统计最长的前k个的长度乘积。

直接构造回文树,每个节点代表着一个本质不同的回文串,排序统计一下即可


codeforces 17E
求一个串中所有相交的回文串的对数。包含算相交
hdu 5157
差不多一个意思

正难则反。相交的不好求我们求不相交的。正反分别扫一边,构造回文树,第一遍记录从某个点开始的回文串数量和,第二遍动态更新答案。\(\Sigma (到i之前为止的回文串*从i+1之后开始的回文串)\)就是所有不相交的回文串对数。总数减去不相交的就是相交的。


URAL 1960
一个串,每次添加一个字母,问这次添加后本质不同的回文串个数。

直接构造回文树,回文树的节点数-2就是本质不同的回文串个数。(因为有两个空节点0和-1)
回文树的一个节点就代表一个本质不同的回文串


codeforces gym 100548G
2014 西安现场赛
求两个字符串的公共回文子串个数

两个串分别建两棵回文树,进行两次dfs(分别从0和-1开始)。每次同时在两棵树上走相同的字母节点,如果能走的通答案就加上\(T1.cnt[x]*T2.cnt[y]\).

因为回文树的形态实际上表示的是回文串自身的结构,如果两棵回文树有长得一样的部分,证明对应的两个串有公共回文子串。


其余题目待补充

posted @ 2015-08-25 17:38  wsc500  阅读(816)  评论(1编辑  收藏  举报