Link
神题。。(哦应该是因为我太弱了。。)
Solution
一直不明白DFS序到底是怎么定义的
那种记录每个点第一次访问的位置的,总共个点,有人叫它DFS序
还有那种记录DFS的路径的,总共个点,有人也叫它DFS序。。
于是各种题解随便一混用就能把我转很久(应该是我太弱了)
好吧,这个用的是第二种DFS序。。那我叫它multiDFS序好了。
首先求出树的multiDFS序
那么求点对距离就是求出LCA然后计算,即为区间最小值
然后求最后一个深度为的节点,只要在序列上二分然后判存在性就行了,判存在的条件是。不要漏掉第二个条件!!
要求把一棵子树移动到它的第个祖先上,首先这个第个祖先也可以在序列上二分得到,而移动在中就对应区间的移动。转化为的基本操作。
这样两个二分就转化为在上走。
But。。
Tips
关于的用法
says ydc

的区间操作一直让我感到云里雾里。 普通的,一般是自顶向下操作(如维修数列),需要一个来在中定位。这样,就可以一路下去,没有问题。 但是在一些直接定位到节点的应用中,比如,它祖先的标记就访问不到了。 学习的时候,看到Po姐的做法是一直递归到根节点,然后一路下放标记。因为也没学会势能分析,也不知道这样复杂度是否有保障,但也就一直这样写了。 在Summer Camp上问了下gty大神,他表示他一直只是在的时候下放一下标记,从来没出现问题。问起关于祖先的标记,他表示没有考虑过。 向gty大神要来代码,最后也没有完全弄明白。 那天晚上跑到省队的实验室去问swh(之前他学的也是类似的写法,只是写hzwer的代码,用手工栈),他说因为操作以后会把节点到根。当时觉得挺有道理的样子,但也没再深究。 写这道题,又用到了直接定位节点需要处理祖先标记的问题。 思考了以下,发现只要按照ydc所讲的,在一个点停下就上去就行了。 在中,需要把父节点的标记下传,然后把当前节点的标记下传,遵循的原则就是:在出子树之前下传防止多传给其它子树,在进入子树之前下传让防止漏传给其它子树。 对于,读取之前本来是可以不需要到根的。(修改也可以在之后) 但现在的话就对读写都一视同仁,都到根,就解决了标记的问题,也让思维更清晰一些。 (特殊情况:提取区间之后对区间进行修改,不能到跟节点,那就修改之后再) 切记对节点进行修改之后要更新区间信息!
Code
1 | //Code by Lucida |