回文树复习小记

来源:互联网 发布:淘宝详情页可以修改吗 编辑:程序博客网 时间:2024/06/01 07:44

之前在某一场富榄出的模拟赛中见到了回文树于是去学习了一发,然后今天再次见到就忘光光了_ (:з」∠) _
于是我觉得很有必要写一发复习小记=w=
首先,回文树和sam类似,是用O(n)的空间存下了所有本质不同的回文串。
但是回文树比sam好实现,原因是一个字符串本质不同的回文串数量就是O(n)的。
因为每次添加一个字符时,假设新增的最长的回文串的长度为D,可以证明只有这个最长的回文串可能是新的本质不同的。
原因嘛,假设这个串是AAAXAAAX,(A代表任意字符,且XAAAX是一个回文串),那么如果新增了一个更小的回文串,设为XBX,可知XBX必为XAAAX的后缀,那么既然XAAAX是一个回文串,于是XBX必为XAAAX的前缀,所以XBX必定存在于之前的状态中。
那么我们可以考虑实现了。
len[i]表示i这个状态所代表的回文串的长度。
trans[i][c]表示i这个状态,在两边加入c这个字符之后所能转移到的状态。
fail[i]表示i这个状态最长的回文后缀,当然不能等于它自己。
类比SAM的建立方法,我们一个个字符的插入。
假设当前字符串结尾所代表的状态为lst,那么我们考虑从lst沿着fail边往上跳,找到第一个点可接纳新加入的字符c作为回文串。
“可接纳”的含义类比SAM大家应该都能理解,这里不再细讲,我们把这个节点设为now。
显然trans[now][c]=newnode
len[newnode]=len[now]+2
因为是在两边都增加。
但是fail呢?显然我们的fail边所指向的状态一定是由now状态的一个回文后缀两边加上一个字符c所得到的,于是我们接着沿着fail边往上跳就好了。
当然如果要求一个回文串的出现次数也是很简单的,留给读者自行思考。
也许我讲的有点抽象,由于博主很懒很菜加上只是写给自己看加深记忆就没怎么配图=w=
感觉比SAM还是要好理解的。。。

原创粉丝点击