树链剖分(P3384)

树链剖分的作用

树链剖分用于解决树上区间询问,主要有两种:

给出两点,询问和修改之间的路径,

又或者给出一个点,询问和修改整颗子树的信息。

树链剖分需要配合其他数据结构如线段树等一起使用

说白了,树链剖分只是根据询问提供正确的区间

针对路径给出区间  的 复杂度为O(logN)

针对子树给出区间 的 复杂度为O(1)


如何实现?

树链剖分,顾名思义,就是把树分成链。

分为重链和轻链,重链就是重儿子连成的链,轻链就是轻儿子连成的链

对于一个点来说,重儿子就是子节点最多的儿子,其他儿子都叫轻儿子。

然后求出下面这些信息就可以实现我们的树链剖分了

int top[N];//表示该点所在的链的最顶端的点是哪个
int size[N];//该点所在的子树的大小
int fa[N];//父节点
int son[N];//重儿子(子节点最多的儿子)
int id[N];//这个节点实际在区间中的位置,就是dfs过程第一次被访问到的时间,就是dfs序啦
int dep[N];//该节点的深度

顺便来个图:

然后怎么求呢?两个dfs即可解决,多的不说,自己看代码(建树用的是链式前向星)

void dfs1(int now,int f,int nowdep){///处理轻重儿子
    dep[now] = nowdep;
    fa[now] = f;
    size[now] = 1;
    for (int i=head[now];i!=0;i=edge[i].last){
        int v = edge[i].to;
        if (v==f) continue;
        dfs1(v,now,nowdep+1);
        size[now] += size[v];
        if (size[v] > size[son[now]]) son[now] = v;
    }
}

int tot;
void dfs2(i
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值