『dfn、树剖杂项』Day9
大融合
麻烦的点在于你每次已经是联通的。所以你每次两个点在并查集里面是联通的。
显然答案是 \((Sum-siz_x)\times siz_x\)。
不妨钦定树深点连向父亲。并查集维护最浅的一个位置的信息。
每次计算 \(siz_x\) 显然要选择较深的一个点。考虑如何计算这个点的答案啊。(其实另外一个点的求法是一样的)
你考虑每次 \(x\to y\) 的修改,将 \(x\) 合并到 \(y\),并且将 \(y\to top_y\) 的路径上都加上 \(siz_x\),这个可以用 bit 树上差分。
\(siz_x\) 也用 bit 求。
是不是很妙。注意用保证一开始每个点的 \(siz=1\)。
Fairy
电压原题。输出方案。
拿出 dfs 树,可以根据每一条返祖边确定环。还是维护每个点的 \(x\to fa\) 的路径的经过环数,还是树上差分。
非常显然地得知一条边必须经过所有奇环并且不能经过任何偶环(在有奇环情况下),否则去掉之后会生出新的奇环。
如何证明返祖边一定不会计入答案?
不想证明了。
Nauuo and Binary Tree
旅行的时候做的。
首先可以确定每个点的深度,考虑按照深度进行构造。
有个 \(n^2\) 就是问之前所有点看哪个回答是 \(1\)。
本质上是找到每次的 \(fa\)。
我们要利用二叉树的性质。考虑每次随机选择一个深度最大的点,查询它和 nowx 的距离。
要么 nowx 在其下面一步,要么在 nowx 到 1 的链上的一个点的另一个儿子里面,暴力跳即可。
发现可以树剖优化过程,每次选择 dfs 的那个点的重儿子链的 ed 节点来询问即可。询问复杂度线性对数。时间由于要暴力跳链所以是平方。
晚测:「NOIP2012」疫情控制
难点在于二分后的贪心。
二分答案。计算每个点能向上走的最大距离,如果走到 1 就记录还剩的距离,因为他还可以向其他子树走。
首先我可以随便用什么判断一棵 1 的子树是否被覆盖满,那么我们一定不会给他安排。
然后就是一堆可以到 1 的点去覆盖所有没有被覆盖满的边,判定性问题。这里贪心最难。
问题在于一个点可以选择覆盖自己原来的点,这样代价更小,否则可能其余点无法完成。
注意到如果剩下的权值 < 到 1 的这条边,那么这个点出去就一定不优,留在原地即可。
发现这样过后,就不会出现这个点无法满足的情况了,所以我们相当于是 2 个序列满足偏序关系的不重匹配,从小到大 two-pointers 就可以了。