• APIO2020


    了一下,作文以记之。

    1. [APIO2020]粉刷墙壁

      • 题意:

        直观描述一下:就是 \(M\) 个人,可以涂一些特定颜色的墙,看成一个环,可以从任意处断开成 \(M\) 个数的数列。 有 \(N\) 个面的墙,对于一连续段长度为 \(M\) 的面,如果 \(M\) 个人可以依次涂这些墙,就代表这一次刷墙是合法的。求最小刷墙次数。

      1. 能发现区间的长度是固定的,任意区间的关系只有相交或分离,求最小覆盖次数,这里面有类似单调性的玩意,这样就很容易有贪心的算法, 类似的有 P4155 [SCOI2015]国旗计划

      2. 问题在于求哪些区间合法。

        一开始一直在想暴力 bitset。其实题目限制埋伏了一手,经过一些推导,发现每一面墙最大只有 \(700\) 个人能涂。

        考虑dp,状态是 \(f_{i, j}\)\(i\) 面墙到 第 \(j\) 个人的时候最多涂了多少墙,能发现状态是 \(N \times M\), 转移时就能利用这个条件优化,空间上就用滚动数组优化。

    2. P6765 [APIO2020]交换城市

      • 题意:

        连通图,两点相互到达各自的点,不能相遇,不是同时走(其中一个点可以不动),每个询问求经过的边的最大值最小。

      1. 首先有想法按照小到大将边加入,再判断能否相互到达,不过这样没有什么前途,虽说有单调性,但整体二分好像做不了。

      2. 其实感觉这种题就是要推充要条件,实际上,两点能相互到达当且仅当两点所在连通块不是一条链。大概就是链的话一定会相遇,如果多出来一个点,那么让一个点暂时待在这个点,等到另一个点路过这个点,再让它出来。

      3. 剩下的问题就是判断连通块是不是链,和解决最大值最小,这时就能想到kruskal重构树,它可以同时解决连通性相关和边权最小/大值的一些问题。按照小到大进行建树即可,维护连通块是不是链应该不是很难,还有一些建树的小问题。最后树上lca即可。

    3. P6766 [APIO2020]有趣的旅途

      • 题意:

        给出 \(N\), 表示这是 \(N\) 个点的二叉树。

        可以询问两点距离和能支配的点的个数。

        \(4 \times 10^5\) 次询问内,求出 \(N\) 个元素排列 \(p\), 满足任意 \(i > 2\), \(\text{dis}(p_i, p_{i - 1}) \geq \text{dis}(p_{i - 1}, p_{i - 2})\),即随着 \(i\) 变大,两点的距离不升。

      1. 实际上没有啥算法能在 \(4N\) 次询问内求出原树,求出树的直径也没事好的想法。

      2. 考虑重心,假如求出重心 \(r\), 它只有两个儿子,那么大小一定分别为 \(\lfloor\frac{n}{2}\rfloor, \lceil\frac{n}{2}\rceil\), 这时只用从较大的子树开始,轮流取深度最大的点,可以发现这样一定满足题意。

      3. 如果他有三个儿子,这时就要分类讨论了。

      • 加入最大的子树大小等于其余两个子树的和,将两个子树合并,按时上面方法即可。

      • 加入最大的子树大小小于其余两个子树的和, 每次在和上一个子树不同的子树内取深度最大的点,总会存在加入最大的子树大小等于其余两个子树的和的情况,这时就可以采用上面的方法。

        但是还要考虑上一次选的子树,来决定这时从哪里开始。

        还有一种特殊情况,假如上一次选的是合并两个子树中的某一个,另一个子树最大深度比大小最大的子树的最大深度大,要再次选回合并两个子树的另一个。

      • 加入最大的子树大小大于其余两个子树的和, 由于重心的定义,这里最大出现大于 \(1\), 在先在最大子树内取一个即可。

      1. 找重心:

        • 在所有 \(n - siz_i <= \frac{n}{2}\) 并且 \(siz_i\) 最小的点是重心。

        考虑以点 \(u\) 为根,而实际上的重心为 \(v\)

        那么只有 \(u,v\) 之间的路径上的点的 \(siz\) 大于 \(\frac{n}{2}\)

        \(siz\) 从浅到深递减,故 \(siz \geq \frac{n}{2}\) 且最小的那个,即为 \(u,v\) 之间路径的最低点: 重心 \(v\)
        ------ command_block

        所以以 \(0\) 为根,求出每个点的子树的大小,按照上面的方法在 \(n\) 次询问求出。

      2. 求每个点到重心的距离 花费 \(n\) 次。

      3. 求每个点在哪个子树,如果有重心三个儿子,不在第一第二个,就一定在第三个,所以最多两次询问,花费 \(2n\) 次。

    总结一下吧:

    1. 题目限制很重要。

    2. 都是交互题的形式,会用交互了,多写能试出平常难以发现的错误, cerr是个好东西。

    3. 对于判定合法问题,最好找充要条件,一般来说不会很复杂。

    4. 有关树的交互题,一般都是利用树的直径,重心的性质,按照一定的贪心策略。

    5. 分类讨论很重要,一步一步思考清楚,老是因为分类讨论出小错误挂,上次 div2 就是这样(好像每次都是这样)。

  • 相关阅读:
    Java开发常用Util工具类
    冒泡排序
    EMQ 消息服务器
    将jar文件包打成exe文件
    mina框架搭建tcp服务器:编写自定义协议及编解码器
    SpringBoot中定时任务的设置
    SpringBoot项目+Shiro(权限框架)+Redis(缓存)集成
    计算两个时间之间的天数
    关于extern的使用
    ADC采样间隔问题+TRGO作为ADC的触发源头
  • 原文地址:https://www.cnblogs.com/qjbqjb/p/16254040.html
Copyright © 2020-2023  润新知