题目大意
一个国家有\(n\)个城市,由\(n - 1\)个道路彼此相连,构成一个树。其中首都(一号节点)紧挨着 艾 雅 法 拉 火山,所以温度\(a_1\)最高,其它城市的温度是随着距离首都的距离而递减的(每条道路长度可以认为是相同的)。现在一种病毒在城市\(i\)爆发,它的可以存活的温度区间是\([l,r]\)。当有道路相连的两个城市温度都可以让病毒存活,且其中一个城市已经被病毒感染,那么病毒就会传播到另一个城市。
给定每个城市的温度\(a_i\)和\(n-1\)条道路,需要回答\(m\)次询问:假如有存活温度范围为\([l,r]\)的病毒在第\(i\)个城市爆发,那么病毒会传染几个城市?
思路
这个题目的思路很好想,就是实现需要一些较难的知识点,主 席 树。(dalao请忽略)
- 病毒在\(i\)城市爆发,那么就向上找到它最高能传染的城市,假设为\(t\)。
- 求在以\(t\)为根的子树上有多少城市的温度大于\(l\)。
第一步可以用倍增等方法在\(O(long(n))\)的时间内求得,而第二步就可能困难了,需要用到主席树。
那么主席树是如何和树上统计联系起来呢?
我们知道,可持久化线段树是可以保留历史版本的线段树了
而利用离散化+可持续化权值线段树 可以实现 查询给定序列某个区间的第k大。(这部分不懂的可以去学习一下)
那么怎么用主席树去实现在树上的查询呢?
首先,我们从\(1\)号节点对整个树进行一次dfs,并给每一个节点一个时间戳,那么dfs完之后,每个节点和它的子节点的时间戳,刚好构成了一个连续的序列。既然有了连续的序列,那么它们的权值就可以通过主席树来维护了。即我们按照时间戳来把每个点的权值排成一个序列,然后用主席树去维护。
那么在树上维护的操作已经解决,那么该如何利用它去解决求在以\(t\)为根的子树上有多少城市的温度大于\(l\)?
我们不妨使用二分法,我们假设有\(k\)个城市可以被传染,然后查询\(t\)的子树上第\(k\)大的城市温度,让它与\(l\)作比较。那么单次查询的时间复杂度就是\(O(log^{2}(n))\)。
代码
1 |
|
- 本文作者: 水蓝络合物
- 本文链接: https://miku39393939.github.io/2021/08/22/Eyjafjalla/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!