虚树
对于多组询问,且每组询问都包含树上一些不同的点的查询的树上问题可能会用到虚树。
虚树的建立
void add(int s)
{
if(!c)
{
vtree[++c] = s;
return;
}
int f = query(pre[s],pre[vtree[c]]);
while((c>1)&&pre[f]<pre[vtree[c-1]])
{
add_edge2(vtree[c-1],vtree[c]);
add_edge2(vtree[c],vtree[c-1]);
--c;
}
if(pre[f]<pre[vtree[c]])
{
add_edge2(f,vtree[c]);
add_edge2(vtree[c],f);
--c;
}
if(!c||vtree[c]!=f) vtree[++c] = f;
vtree[++c] = s;
}
另外,固定一个根每次加入(比如1)会好一点。
练习
CF613D
建立虚树,之后树形dp.
SDOI消耗战
建立虚树,树形DP,刚开始想维护任意父子间最小距离,其实只用维护到1节点的最小值就可以了,还是不够灵活。