ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

APIO2020

2022-05-10 16:35:35  阅读:170  来源: 互联网

标签:子树 frac 题意 重心 siz 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 就是这样(好像每次都是这样)。

标签:子树,frac,题意,重心,siz,APIO2020,最大
来源: https://www.cnblogs.com/qjbqjb/p/16254040.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有