vtree

虚树套餐(随缘更新)

旧城冷巷雨未停 提交于 2020-08-19 19:06:52
由于本人太菜,所以字符串专题只学会了虚树一个知识点,所以写文乱giao 首先假装大佬地讲一下虚树: 虚树主要用于优化树DP,由于有些题hin贱,会有多次查询修改,还只查询一些关键点,此时直接树DP就跑不过去了。 这时我们想到,能不能减少点的个数,使树DP能跑得飞快呢? 学的时候联想到了这题,说不定也能用虚树做 我们通过把一条链压缩成一条边来简化这棵树 比如这棵树,黑色点是关键点,简化后就变成了 这时我们懒得遍历2 3 6 4这些节点了,反正也没用(-_-) 但是7号节点还是有必要留,毕竟还要递归嘛~~ 但怎么找到所有要保留的点并连边呢 维护右链 我们开一个栈,记录当前“最靠右的链” 先连接1号节点和最靠左的关键节点 8号节点 (红色是关键点,蓝色是右链,节点3 7都被压成了一条边) (是的,右链一开始是在左边的) 然后我们要让右链不断“往右移” 我们于是把更加“靠右”(是的,就是 物 理 靠 右 )的9号点添加进来,但是我们不能“把一个点加到一条边上”啊 我萌就把右链底端的8号点和新加入的9号点的lca:7号点还原,从而加入9 重复以上操作就可以构建出虚树 什么,你问怎么找到“物理靠右”?肯定是dfs序啦. void build_vtree(ll x){ if (tt== 1 ){ st[ ++tt]= x; return ; } ll lca = L_C_A(st[tt],x);