cf258e

此题和前面两个dfs序列其实是差不多的。只是稍微复杂点。

首先需要明白:某个点的子树就是DFS序列里一段连续的区间。所以我们要给其子树赋值,就是给对应的dfs序列中的连续区间赋值。

那么首先用dfs预处理出连续区间。然后离线的保存所有的询问。然后按dfs序列来搜,每搜到一个节点,则更新其区间,然后统计出来有多少个就可以了,这和前面的那两题是差不多的。这个步骤可以用线段树来维护,或者树状数组来维护。然后退出的时候要保证不影响其他的点,那么退出的时候-1操作来复原就好了,类似于usaco那题。

以下这一段来自:http://hi.baidu.com/lydrainbowcat/item/7daee04e7df29e94823ae1c7

然后:统计答案的时候,DFS一遍,对于一个点x,以下操作会对其造成影响:

(0)只要有涉及x的操作,以x为根的子树中所有节点必定和x有公共部分。

(1)形如(x,y)的操作。这样显然以y为根的子树中所有节点都与x有公共部分。

(2)形如(fa,z)的操作,其中fa是x的祖先。以z为根的子树中所有节点也与x有公共部分。

因此DFS进入点x时,把x为根的子树、以及从x出发的所有操作对应的y为根的子树的DFS序列区间都+1,退出时都-1。

线段树中,如果一个区间被+过,那这整个区间就与x有公共部分,否则应该用左右孩子的公共部分来更新它。每次直接ASK线段树根节点即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值