Noip 2018前最后一篇博客

去年还猜了要考什么,然而果然猜错了。我还是毒奶今年会考去年写的这个。

只要不出什么大搜索之类的东西就行。

赛前本来还想学一下一直没怎么搞明白的东西,然而发现还是不会,于是跪了。

反正现在还不会什么 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加入栈中,这个栈中就会一直有点了。

然后,完了。

你可能感兴趣的:(优化,总结,虚树)