A. 倚天剑的愤怒
考虑特殊的情况,如果 $a_i <0$ ,那么最优的决策一定是把最差的跳过。
然后可以考虑如果存在一个 $a_i>0$ ,那么这个 $i$ 无法对前面的操作产生影响,但是可以是把后面的一些小于 $0$ 的元素抵消掉。
抵消之后呢?问题仍然是把最差的跳过。
所以贪心的策略是,维护一个大根堆,倒着考虑每一个元素。
如果当前元素小于 $0$,那么直接加入堆。
如果当前元素大于 $0$,那么不断尝试抵消堆顶元素。
最后单调指针扫一遍就好了。
B. 原谅
枚举答案这个分界点的值。
然后可以考虑首先把大于等于分界点的点都加入并查集中。
考虑当前的情况,如果有超过 $1$ 个连通块中含有大于分界点的值,那么显然问题无解。
否则可以仅考虑含大于分界点的值的连通块,通过一个类似拓扑排序的东西不断删掉叶子结点就好了。
C. 收集
考虑选出这些含有宝物的点来,构造一棵虚树。
然后选择一个起点一个终点,容易发现可以的采取最优决策是
使两个点之间路径上的边经过一次,其他虚树上的边都经过两次。
所以答案是 $2*sum - len$,所以要维护的是虚树上关键点的直径和生成树权值和。
因为我太菜,所以只会线段树分治。
只考虑加入元素。那么维护直径可以直接用经典的维护两个端点的方法。
我的维护生成树权值和的方法更加弱智,考虑树剖。
那么每次增加节点的时候任选一个原来的节点,统计新增节点到原有节点路径上没经过的边即可。
对每个线段树上的节点维护两个标记,表示该节点是否完全覆盖、是否完全没被接触过。
如果满足其一,那么可以直接返回答案。
因为本题的特殊性质,一条重链上最多只有一个连通块。所以这样做的复杂度是 $O(nlog^3n)$ 的,就非常菜。
动态维护直径似乎是一个经典问题,直接在线段树上维护点集直径就完事了。
而生成树权值和,容易发现按 $dfs$ 序排序之后,统计每两个相邻的点的距离之和就完事了。
原文地址:https://www.cnblogs.com/skyh/p/12384704.html