zoukankan      html  css  js  c++  java
  • 省选模拟34 题解

    A. 倚天剑的愤怒

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

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

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

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

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

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

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

    B. 原谅

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

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

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

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

    C. 收集

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    反射
    java 验证码识别
    Spring boot + mybatis + orcale
    JVM内存模型及垃圾回收的研究总结
    Java的Array和ArrayList
    Java中最常见的十道面试题
    session和cookie
    Hibernate的load()和get()区别
    ajax跨域获取网站json数据
    对于Spring的IOc和DI的理解
  • 原文地址:https://www.cnblogs.com/skyh/p/12384704.html
Copyright © 2011-2022 走看看