A - Painting Walls
可以发现,题中所谓的要求作为一个二元组 ((x,y)),看上去有 (O(NM)) 个,没算上判定的时间就已经远远超出承受范围了。但思考得知,我们要求本质上是刷这 (N) 个墙壁,而每次刷的区间长度固定为 (M),也就是说只有 (O(N)) 个本质不同的刷墙方法,这成为我们的突破口。
换言之,我们需要对于每个 (i) 得到是否存在合法的从 (i) 开始的刷墙要求。考虑一个朴素的动态规划:(f(i,j)) 表示从 (i) 这堵墙开始,如果第一个指派的承包商为 (j),按题意循环最多可以连着刷多少。那么显然:
最后对于每个 (i) 都检查是否存在一个 (j) 满足 (f(i,j)ge M) 即可。
但这个 dp 貌似是 (O(NM)) 的,实则不然,因为有 (sum f^2(k) le 4cdot 10^5),也就是说 (f(k)le sqrt {4cdot 10^5}),这意味着每个 (i) 中有效的 (j) 并不多,那不需要存下所有状态就能在可承受的时间内 AC 了,复杂度 (O(Ncdot sqrt{sum f^2(k)}))。
B - Swapping Cities
首先考虑无解的充要条件是什么。简单手玩可以发现具体的方案要么就是绕出一个圈,要么就找一个岔路避让,而唯一的不可行方案是链状的图。而一个连通图是链,当且仅当其上没有超过 (2) 度的点其无环。
如果是一辆车,那答案就是最小瓶颈路。考虑这里很可能就是最小瓶颈路的变式,尝试 Kruskal 重构树。首先对于询问 (X,Y),答案不可能低于最小瓶颈路,那可以先找到 (X,Y) 在重构树上的 LCA (L)。假如说 (L) 所表示的连通块已经不是链了,那显然 (L) 对应的边权就是答案。反之,我们肯定是继续对连通块 (L) 按权值从小到大依次加边,直至出现环或分叉为止。对于环,可以在跑 Kruskal 时用并查集判,发现就在对于连通块上的结点挂着;对于度数只要开个数组记一下,打个标记就行。最后一遍 Dfs 处理出最近产生非链连通块的祖先。
复杂度 (O((N+Q)log N+Mlog M)),瓶颈 LCA 和排序。
C - Fun Tour
挺神仙的交互 + 构造。
首先,用 (O(N)) 次询问获取完整的树形态是比较困难的,这说明我们构造一组解不一定依赖完整的树结构。
不过我们还是考虑一下给定了树怎么做。非常重要的一点:度数不超过 (3)。若是我们随意定一个根,那么可以每次选一个深度最大的点,满足与上一次选择的 LCA 为根,也就是说不在根同一个儿子的子树内。可以保证这样的方案必然距离不增。但这就要求根的各个子树尽可能均匀,而这和重心的概念与性质十分吻合。
那么选一个重心作为根,那么根的度数为 (2) 或 (3)。稍微讨论一下:
- 根有两个儿子:由于以重心为根的子树大小不超过一半,那么两棵子树的大小差显然不超过 (1),直接轮流取必然存在合法解。
- 根有三个儿子:若三个子树大小为 (a,b,c),不失一般性设 (age bge c)。根据重心的性质有 (ale b+c+1)。思考按这样的方式不断操作,由于 (b+c) 减小的次数不小于 (a),那么最终会有 (a=b+c+1) 的局面出现。这时候不妨合并 (b,c),从而归约到两个儿子的情况。注意一个 corner case,就是当前刚刚选了 (b) 然后 (a=b+c+1),但是下一个最大的应该在 (c) 中,那应该在手动操作一次 ,否则可能会出现不合法的结果。
最后就是通过不超过 (4N) 次询问,处理出:
- 树的重心;
- 以重心为根每个点的深度;
- 每个点分别属于重心的那个子树。
前两者不难得到,其中重心可以先任意定根,然后求出每个子树的大小,最后子树大小 (ge leftlceilfrac{n}{2} ight ceil) 中大小最小的即为重心。于是前两个要素需要 (2N) 次询问。对于最后一个,很显然如果 ( ext{dep}_x + ext{dist(x,y)}= ext{dep}_y) 那 (y) 就是 (x) 的后代。考虑到度数不超过 (3),那只要询问两次距离(第三个可以排除前两个)就行了。最后总询问次数不超过 (4N)。复杂度 (O(Nlog N))。