题目链接(luogu)
看到标签::树链剖分,蒟蒻Sy开始发抖,不知所措,但其实,本题只需要一个恶心普通的操作就可以了!!
前提知识:欧拉序
首先我们知道dfs序,就是在dfs过程中,按访问顺序进行编号。
而Eulor序,就是在退出时也加入编号。
举个栗子:
dfs序:1 2 4 5 3
eulor序:1 2 4 4 5 5 2 3 3 1
有些dalao又要问蒟蒻我eulor序有什么用,我们来找下规律:
1~5的路径中经过了1、2、5共3个点,而在eulor序1~第1次出现5的位置
1、2、5只出现了1次,而其他数出现了2次
再试几次后,发现同样成立,
1个点在第2次出现时其子树一定遍历完了,而1-i的链中一定只有上下关系,没有兄弟关系
所以eulor序中出现了2次 或0次(这不是废话吗)的一定不在链上,反之亦然
而我们又可以发现一个节点的子树一定出现在它2次出现之间。
接下来解法就好想了:
操作1:x第1次出现的位置加a,第2次出现的位置加-a
操作2:x第1次至第2次出现的位置,第1次出现的点a,第2次出现的加-a
操作3:输出1~x第1次出现的位置的和(因为出现了2次的点第1次与第2次的和相抵消了)
初始值就把第1次出现的位置赋为vi,第2次赋为-vi,用线段树维护。
但怎么在一个区间,一些加,一些减呢?
dalao:Link-cut tree、splay、AA树,太简单了
蒟蒻:。。。
总所周知,sy是个蒟蒻,不会打高级数据结构,所以这里介绍1种简单方法。
给节点数分正负
例如:
本人手残,
(叶子节点左边为eulor序,右边为节点大小。其他节点只有大小)
具体实现看 注意!此代码加了防抄袭措施的