题意复述:给一棵树,每条边上有一个字符((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两行泪