字典树学习笔记
字典树,顾名思义,就是一棵能当字典的树。先来看板子:
给 n 个模式串和 q 次询问,对于每次询问,求有多少个模式串满足询问串是模式串的前缀。
字典树的概念不必说(因为这是写给我自己看的笔记),对每一个点记录一个值 cnt[i]
,在插入时,路径上的每一个点 cnt[i] ++
,表示这个节点表示的字符串又多当了一个字符串的前缀。在查询时,如果这个查询串走到一半往下走不动了,意味着它并不是某一个字符串的前缀,就可以 return 0
了。
AC code:
求最长的异或路径,就是路径上边权的异或和。
设 dis(u,v) 表示 u 到 v 的异或路径。所以有:
dis(u,v)
= dis(u,LCA(u,v)) ⊕ dis(v,LCA(u,v))
= dis(u,LCA(u,v)) ⊕ dis(v,LCA(u,v)) ⊕ dis(LCA(u,v),Root) ⊕ dis(LCA(u,v),Root)
= dis(u,LCA(u,v)) ⊕ dis(LCA(u,v),Root) ⊕ dis(v,LCA(u,v)) ⊕ dis(LCA,Root)
= dis(u,Root) ⊕ dis(v,Root)
所以我们可以预处理出所有的 dis(u,Root),然后扔到01字典树里。枚举每一个 u,在字典树上,如果 disu 的第 x 位取反有对应的子树,就往哪里走并记录答案,因为这样能让那一位异或后变成 1。否则就往另一个子树走,不更新答案
AC code: