A. 倚天剑的愤怒

考虑特殊的情况,如果 $a_i <0$ ,那么最优的决策一定是把最差的跳过。

然后可以考虑如果存在一个 $a_i>0$ ,那么这个 $i$ 无法对前面的操作产生影响,但是可以是把后面的一些小于 $0$ 的元素抵消掉。

抵消之后呢?问题仍然是把最差的跳过。

所以贪心的策略是,维护一个大根堆,倒着考虑每一个元素。

如果当前元素小于 $0$,那么直接加入堆。

如果当前元素大于 $0$,那么不断尝试抵消堆顶元素。

最后单调指针扫一遍就好了。 

 

B. 原谅

枚举答案这个分界点的值。

然后可以考虑首先把大于等于分界点的点都加入并查集中。

考虑当前的情况,如果有超过 $1$ 个连通块中含有大于分界点的值,那么显然问题无解。

否则可以仅考虑含大于分界点的值的连通块,通过一个类似拓扑排序的东西不断删掉叶子结点就好了。

 

C. 收集

考虑选出这些含有宝物的点来,构造一棵虚树。

然后选择一个起点一个终点,容易发现可以的采取最优决策是

使两个点之间路径上的边经过一次,其他虚树上的边都经过两次。

所以答案是 $2*sum - len$,所以要维护的是虚树上关键点的直径和生成树权值和。

因为我太菜,所以只会线段树分治。

只考虑加入元素。那么维护直径可以直接用经典的维护两个端点的方法。

我的维护生成树权值和的方法更加弱智,考虑树剖。

那么每次增加节点的时候任选一个原来的节点,统计新增节点到原有节点路径上没经过的边即可。

对每个线段树上的节点维护两个标记,表示该节点是否完全覆盖、是否完全没被接触过。

如果满足其一,那么可以直接返回答案。

因为本题的特殊性质,一条重链上最多只有一个连通块。所以这样做的复杂度是 $O(nlog^3n)$ 的,就非常菜。

动态维护直径似乎是一个经典问题,直接在线段树上维护点集直径就完事了。

而生成树权值和,容易发现按 $dfs$ 序排序之后,统计每两个相邻的点的距离之和就完事了。