Hdu 3887 Counting Offspring \\ Poj 3321 Apple Tree \\BZOJ 1103 [POI2007]大都市meg
这几个题练习DFS序的一些应用。 问题引入: 给定一颗n(n <= 10^5)个节点的有根树,每个节点标有权值,现有如下两种操作: 1、C x y 以节点x的权值修改为y。 2、Q x 求出以节点x为根的子树权值和。 最直观的做法, 枚举一个子树内所有节点的权值加和。但这种做法的每一次讯问的时间复杂度是O(n)的,很明显无法满足题目的需要,我们需要更优的解法。 我们考虑DFS序的另外一种形式,当访问到一个节点时记下当前的时间戳,我们设它为L[x], 结束访问一个节点时当前的时间戳设为R[x]。则以x为根的子树刚好是下标为L[x]和R[x]中间的点。我们看下面这个例子。 有了DFS序这个性质我们就可以讲这个问题转化成一个区间求和问题。 每一次询问的复杂度就是O(logn)级别的,完全可以接受。 另外:很多人习惯在生成DFS序的时候,叶子节点的进出时间戳差1,我习惯于叶子节点的进出时间戳一样。这样根节点的时间戳为[1,n] 比如说:上图中如果采用叶子节点进出时间戳差1的写法,DFS序为:4、3、1、7、7、1、2、6、6、2、3、5、8、8、5、4.数量为2*n 如果按照我习惯的做法,DFS序为:4、3、1、7、2、6、5、8. 两种做法都可以,我习惯于第二种。 练习题: 第一题: http://acm.hdu.edu.cn/showproblem.php?pid=3887 题意