HDU 4366 浅谈DFS序+线段树

本文探讨如何将树上的查询转化为序列问题,利用DFS序和线段树解决。针对寻找子树内忠诚度最高且能力值大于当前查询值的个体,通过先对能力值排序,然后按忠诚度建立线段树,实现区间最大值查询。这种方法能有效处理能力值的范围要求,简化问题解决过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
世界真的很大
对于树上的询问要有意识地去想要不要吧树上问题转化成序列问题,就可以用线段树一类的数据结构来维护了
DFS序和树链剖分都是很不错的把树转换为序列问题的方法
看题先:
description

给一个树,树上每个节点都有两个属性:忠诚度和能力,给出若干查询,求每个子树中能力 > 树根能力的点中,忠诚度最高的那个
n≤50000
数值≤1000000

input

第一行一个整数T,表示数据组数
每一组数据第一行两个整数n,m,表示树有n个节点,有m组操作
接下来n-1行每行两个整数u,v,表示u,v之间有一条边

output:

对于每一个询问一个整数t表示答案,没有就输出-1

如果不管能力值得话,就相当于在一个数的子树里找一个忠诚度最高的,显然可以用DFS序后加以线段树解决,区间最大值而已
然后考虑怎么解决能力值得问题
仔细看来能力值并不是像忠诚度那样要求最大,只是需要大于当前查询的就行了,换句话就是说,只要能力值不比当前的大,不管是在子树外面还是里面,都对答案没有贡献,对于每一个人,有可能替代他的就只有能力值比他大的而已,再在这些人里面选一个在其子树里面忠诚度最高的
思路出来了,这个思路也是很重要的
对于两个要求条件,可以把其中一个只是范围要求的要求,排序。先建一颗空树,将能力值排序后再按忠诚度加入线段树,这样在查询任意一个人时,线段树里有的值都是比当前人能力值大的
完整代码:

#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值