Text
由于实在太简单,我尽可能简略
回文树的每个节点代表了原串的回文子串
维护两个树,一个是偶长度,一个是奇长度
每个点维护len、fail、出边
len就是代表回文串的长度
fail就是这个串的最长回文后缀的位置
假设当前字符串为Sx,走的这个边是字符c的
那么走到的字符串就是cSxc
考虑增量法构造
在末尾加入一个子符,那么从last开始沿着fail找到第一个可以两边加这个字符的位置,它新开一个这个字符的儿子(有就不用了)
再从他开始沿着fail找,找到第二个可以两边加这个字符的位置,那么新开的这个点的fail连向找到的第二个点的这个字符的儿子(有就不用了)
那么为什么只用找到第一个和第二个呢
因为第一个以后的一定都是第一个的回文后缀,根据回文的定义,既然有这样一个回文后缀,那么一定有一个跟他一样的回文前缀,所以它一定在前面已经出现过,不必继续做下去
总空间复杂度O(N*字符集大小),时间复杂度O(N*字符集大小*log)
此处不给证明
模板嘛,Emmm…