去年还猜了要考什么,然而果然猜错了。我还是毒奶今年会考去年写的这个。
只要不出什么大搜索之类的东西就行。
赛前本来还想学一下一直没怎么搞明白的东西,然而发现还是不会,于是跪了。
反正现在还不会什么manacher\text{manacher}manacher,类欧之类的鬼畜玩意。
下面进入正题
虚树
树上有k\text{k}k个点,然后枚举两两个点,加入他们的lca\text{lca}lca然后构成的树。大小是O(k)\text{O(k)}O(k)的。
考虑怎么做:先按照点的dfn\text{dfn}dfn序排序,然后维护一条链,表示当前维护的一个东西,这个用一个栈来实现,如果当前栈顶的点是top\text{top}top,新加入的点为p\text{p}p,然后分情况讨论:
1)lca(top , p) = top\text{lca(top , p) = top}lca(top , p) = top 说明这个p\text{p}p还在链上,直接加上去就好了。
2)否则,top\text{top}top与p\text{p}p分别位于lca\text{lca}lca的两个不同的子树中,我们现在就要把top\text{top}top这颗子树处理完,怎么做,一直pop\text{pop}pop呗,直到跳到了lca\text{lca}lca或者lca\text{lca}lca的祖先。这里要注意的是如果lca\text{lca}lca不在栈中,要把lca\text{lca}lca加入栈中。
为了防止一些无聊的特判,先把1\text{1}1加入栈中,这个栈中就会一直有点了。
然后,完了。