【题解】yww 与树上的回文串

题目链接

题意复述:给一棵树,每条边上有一个字符((0)(1)),求有多少对 ((x,y)(x<y)),满足 (x)(y) 路径上的边上的字符按顺序组成的字符串为回文串。

又一道神仙题啊

用其它方法并不能方便地求出答案,考虑点分。

经过一个点的回文串只有两种情况:

  • 该串被这个点分成两段长度相等的子串,且两个子串对称。
  • 该串被这个点分成两段长度不等(可能为(0))的子串,且长串由短串与一个回文串拼接而成。

先找出以重心为开头的所有路径所表示的字符串,考虑第一种情况:可以建一颗字典树,查找表示每个字符串的路径的数量,就可以算出终点不同且表示相同串的路径数。

再来考虑第二种情况:即长串的后半段与短串匹配。由于有多个串要匹配,就可以建立AC自动机,根据定义可得短串的终点在fail树上是长串的祖先。

根据broder理论

一个回文串的所有回文前缀可以被表示为(O(log n))个等差数列

可以记录下长串在Trie树上的所有回文前缀所构成的等差数列,再在fail树上dfs,用数组记录当前访问节点的祖先中每种长度的串的数量,根据等差数列计数的套路,用(sqrt{n})个长度为(sqrt{n})的数组来记录公差(leqslant sqrt{n})的情况,同时记录下所有长度,就可以做到(O(sqrt{n}))修改与查询。

求回文前缀可以有Trie树上父亲的状态转移而来,判一个串是否为回文串可以用字符串哈希。膜数不选好,爆0两行泪

代码太丑不贴了……

原文地址:https://www.cnblogs.com/ztc03/p/12026091.html