【题解】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两行泪

代码太丑不贴了……

猜你喜欢

转载自www.cnblogs.com/ztc03/p/12026091.html