标签:信息 顶点 class swa bsp text ... play wap
然而并不熟练剖分(雾);
他可以做什么?(大雾)
熟练想必是在熟上的练(雾雾雾)
#define 树链 熟练
树链剖分即把树剖成很多条链,有的长有的短;
主流剖法:
1.随机:O(1 ~ 脸 ~n)均摊后 log ;
2.轻重链:O为 log 级 也即这里的熟练剖分;
非主流剖法:
机房某大佬自创的按链长剖分,看起来还不错,中了迭代加深的毒吧;
下面就是蒟蒻我的不熟练剖分了;
1.st 分链
以两遍dfs解决;
dfs1 找出每个节点重儿子 , 顺带上 fa,deep等数组;
dfs2 确定每条重链的顶点 ,链接各个重儿子 , 顺带上 nid 等数组;
void dfs1(int fu,int cur,int depth) { dep[cur]=depth;//深度 fa[cur]=fu; //记录父亲,递归中用于无向图判断搜索方向,以及后来的转换重链 sub[cur]++;//子树大小,自己为根,叶结点为1; int pang =-1 //预备记录胖儿子 for(int i=Head[cur];i;i=bian[i].NE) { int _v=bian[i].TO; if(_v==fu)continue; dfs(cur,_v,depth+1); sub[cur]+=sub[_v]; if(sub[cur]>pang) { pang=sub[cur]; zhong[cur]=_v;//记录胖儿子的数组 } } }
void dfs2(int cur,int tp)//tp即重链顶端 { din[cur]=tp; dfn[cur]=++dfsxu;//记录dfs序 //同一链上的节点必定dfs序相连 nid[dfsxu]=quan[cur];//以dfs序为下标存点权,方便调用 //这个数组,nid,卡懵了我很久,望周知; dfs(zhong[cur],tp);//胖儿子优先 且在相同链上 tp相同; for(int i=Head[cur];i;i=bian[i].NE) { int _v=bian[i].TO; if(_v==zhong[cur]||_v==fa[cur])continue; dfs(_v,_v);//轻儿子以自己为顶点,有自己的一条重链 } }
2.nd 构造
以dfs序够造线段树(每条链都有)
每个结点相当于以前处理数组时的原数组;
(支持区间操作的结构(splay,zkw,树状数组,lct,。。。)都行,我就不暴露自己的真实实力了(逃))
3. 区间操作
在同一链上的话,口糊就好,因为我们已经把同一条链上的信息收集过了,直接调用;
不在呢?谁知道...
蒟蒻我偷听几位大佬讨论后,发现其实是一个找LCA向上跳点的简化过程;
大致如下:
1 :if tp【i】!= tp【j】 == 》2 ; else ==》 4;
2 :if(dep【i】> dep【j】)swap(i,j);||
标签:信息 顶点 class swa bsp text ... play wap
原文地址:https://www.cnblogs.com/hjk-biu/p/9388386.html