首先考虑怎么构造一个方案,首先先反过来,然后考虑对于一个起点,把不同儿子的点按照深度从小到大轮流跳。不难发现只要不存在一个子树的大小 > n 2 >\frac{n}{2} >2n,就一定有解。
至于构造方案,设 r e s res res为剩下的点, m x mx mx为最大的子树的大小,当前满足 r e s − m x ≥ m x res-mx\ge mx res−mx≥mx,每一次选择其他子树中最浅的没有被选择的点,那么最后一定有一个时候满足 r e s − m x = m x res-mx=mx res−mx=mx,然后一个简单的思路就是在 m x mx mx和 r e s − m x res-mx res−mx中轮流选即可。
这个部分有一点细节,比如最后轮流选要考虑一下有没有更浅的点没有选择。
现在我们需要找到重心,以及它的所有儿子,每一个点属于哪一个儿子,以及它的深度。
寻找重心的过程可以考虑从根每一次往一个 s z sz sz最大的点走。
首先询问以0为根,所有点的深度。
然后从0往下面走,当前的点是 x x x,则找到所有 d e p [ y ] = d e p [ x ] + 1 dep[y]=dep[x]+1 dep[y]=dep[x]+1的 y y y,询问它们到 x x x的距离,如果距离是 1 1 1那么就是 x x x的儿子,否则它在父亲的子树内,把 y y y跟 f a x fa_x fax连一条长度为 d i s − 1 dis-1 dis−1的边。
之后询问儿子的 s z sz sz,找到一个最大的走下去。
确认重心 x x x之后只需要对于 d e p [ y ] > d e p [ x ] + 1 dep[y]>dep[x]+1 dep[y]>dep[x]+1的 y y y问 y y y到三个儿子中的两个的距离,由于我们知道这三个距离分别是 d , d + 2 , d + 2 d,d+2,d+2 d,d+2,d+2所以知道两个相当于是知道第三个,因此可以直接找到它属于哪一个子树、它到根的距离。
一开始 n n n次询问,考虑前一部分的点,找 s z sz sz和 d i s dis dis最多要 2 2 2次,后一部分的点问两个儿子最多要 2 2 2次,因此只需要小于 3 n 3n 3n的操作数即可完成询问。