虚树学习笔记


虚树听起来还是很牛逼的,,,,但是尝试学一下之后发现其实并麻油很难,,,,至少基本的操作还是比较简单的(虽然题目对我来说都还是比较难的QAQ

它可以理解为一棵树的压缩版,就是假如选取一部分点集,此时很多节点都是无用的,但是在做的时候又会做到,复杂度就不对,这个时候就考虑建一棵虚树——也就是重新建一棵树,只保留有用的点(给定的点集&他们的lca

图就不放辣不喜欢画图QAQ在网上搜题解应该基本上都有图的趴QAQ

然后说下虚树的性质,建立,常见应用,以及经典题目,就差不多辣QAQ

虚树の性质

m个给定节点形成的虚树的节点不超过2m-1

简要证明:

由虚树的性质可得,如果一个节点不是给定节点,它只能是lca,所以任意一个非给定节点都必定有至少2个节点,所以节点数不超过2m-1

所以虚树的单次复杂度都是O(size)的

所以虚树通常用来解决多次询问给定不同点集且点集总量比较小的问题w

虚树の建立

有两种,分别说下w

第一种是维护最右链,其实就是说维护一个栈,保证栈中的元素在一条链上

具体来说就首先dfs求出dfn什么的基本属性不说

然后每加入一个点x,算出x和当前栈的栈顶y的lca,然后判断

首先如果lca=y,说明依然在这条链上,将x压入栈就好

然后如果lca!=y,就一定是y比lca还要深一些,就是x在另一条链上

因为我们首先是按照dfn的性质给点排了序的,所以由性质可得,直接把栈中深度大于lca的点都弹出去,然后加入lca和x就可以辣

然后其实还是比较好理解的,,,尤其结合图像简直一目了然,所以可以自己画一下所以推荐一下psj的学习笔记,,,配了图然后讲得也极好QAQ

il void build()
{
    head_stck=cnt_edge_fk=0;
    rp(i,1,cnt_ld)
    {
        if(!head_stck)stck[++head_stck]=land[i];
        else
        {
            ll grd=lca(stck[head_stck],land[i]);if(grd==stck[head_stck]){stck[++head_stck]=land[i];continue;}
            while(dep[stck[head_stck-1]]>dep[grd])ad_fk(stck[head_stck-1],stck[head_stck]),--head_stck;
            if(grd!=stck[head_stck-1])ad_fk(grd,stck[head_stck]),stck[head_stck]=grd,stck[++head_stck]=land[i];
            else ad_fk(grd,stck[head_stck]),stck[head_stck]=land[i];
        }
    }
    while(head_stck>1)ad_fk(stck[head_stck-1],stck[head_stck]),--head_stck;rt=stck[head_stck];
}
具体实现代码w

第二种比较简单粗暴,就根据dfn序的性质,直接把点集按dfn排序,然后两两点的lca算出来,把lca和点全部加入虚树,记得去重就是辣

这儿就很显然嘛,首先可以想到,正解方法得到的子树一定是这个方法的子树的子集

所以只是买有压缩完全的问题,首先不会影响正确性这个很显然

然后再加上这么做的复杂度显然是对的(只是常数怕是有点大,,,?

所以这么做不管是正确性还是复杂度都过得去,就麻油问题辣

优点大概在于很简单很容易打完,而且复杂度是一样的w

il void build_fk()
{
    sort(land+1,land+1+ld_cnt,cmp);
    my(i,ld_cnt,2)land[++ld_cnt]=lca(land[i],land[i-1]);land[++ld_cnt]=1;
    sort(land+1,land+1+ld_cnt,cmp);ld_cnt=unique(land+1,land+1+ld_cnt)-land-1;
    rp(i,1,ld_cnt)
    {
        while(head_stck && dep[stck[head_stck]]>dep[land[i]])--head_stck;
        ad_fk(stck[head_stck],land[i],dep[land[i]]-dep[stck[head_stck]]);
        stck[++head_stck]=land[i];
    }
    return;
}
大概长这样儿?不清楚有麻油打挂,,,有的话请指出昂QAQ

虚树の应用

求实树上任意一点到虚树上的最短距离

就是世界树那题,,,明天写QAQ

虚树の题目

明天写QAQ先随便写几个QAQ

[X]消耗战

[X]世界树

[X]大工程

[X]毒瘤

[ ]CF613D

[ ]战略游戏 (还要会圆方树+链并嘤嘤嘤

[ ]寻宝游戏 (同上QAQ

[ ]CF809E (还要会Mobius反演嘤嘤嘤

[ ]暴力写挂 (还要会边分治嘤嘤嘤

[ ]通道 (同上QAQ

[ ]CF613D


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM