首页 > 其他分享 >ABC364 DEF 题解

ABC364 DEF 题解

时间:2024-07-28 22:41:36浏览次数:13  
标签:Box 连通 le color 题解 菜肴 节点 DEF ABC364

ABC364 DEF 题解

D - K-th Nearest

题目链接

赛时想了一个(也许确实是对的)做法,但是代码太难写,一直没写出来……看了官方题解才发现正解其实也很简单……

本题最关键的一点是要转换思路:与其考虑“离某个点第 \(k\) 近的点在哪”,不如考虑“离某个点距离不超过 \(x\) 的点有多少个”。想到这一步转换,这道题就完成 \(80\%\) 了,因为之后的想法都非常顺理成章。

设 \(f_i(x)\) 表示在 \(A_1, A_2, \cdots, A_n\) 中,离 \(B_i\) 距离不超过 \(x\) 的点的数量。不难看出,只要找到最小的满足 \(f_i(x) \ge k_i\) 的 \(x\),那么 \(x\) 就是答案。而 \(f_i(x)\) 显然是单调递增的,所以可以二分。

最后,如何计算 \(f_i(x)\) 呢?可以将 \(A_1, A_2, \cdots, A_n\) 从小到大排序,然后我们要做的就是计算落在 \([B_i - x, B_i + x]\) 中的点数。因为 \(A\) 已经有序了,可以简单地使用 lower_boundupper_bound 来查找。

AC 记录

E - Maximum Glutton

题目链接

看到这题,首先想到二维费用背包:设 \(f(i, x, y)\) 表示在前 \(i\) 道菜肴中,甜度不超过 \(x\),咸度不超过 \(y\) 的情况下,最多能吃多少道菜肴。需要注意,因为甜度或咸度超过限度时才会停止,所以在吃掉 \(f(N, X, Y)\) 道菜肴之后,他还可以再吃一道(如果还有菜肴的话),因此答案为 \(\min(N, f(N, X, Y) + 1)\)。

但是,二维费用背包的时间复杂度是 \(O(NXY)\),在本题中无法接受。注意到 \(N\) 很小,这时应该考虑改变状态设计,并尽可能在下标中用和 \(N\) 有关的量替换掉 \(X\)、\(Y\) 有关的量,这样就可能减小时间复杂度。

重新设计状态:设 \(f(i, j, k)\) 表示在前 \(i\) 道菜肴中选择 \(j\) 道吃掉,使得总甜度值为 \(k\) 时,这些菜肴的最小总盐度值。这样,状态的前两个维度都和 \(N\) 有关,又因为转移的时间复杂度是 \(O(1)\)(见下),所以总的时间复杂度就降到了 \(O(N^{2}X)\)。想到这样设计状态,接下来也就十分简单了。

答案统计:找到最大的满足 \(f(N, j, k) \le Y\) 的 \(j\),则答案为 \(\min(N, j+1)\)。(\(0 \le k \le X\))

转移方程:\(f(i, j, k) = \min(f(i-1, j, k), f(i-1, j-1, k-a_i)+b_i)\),括号中两项分别考虑选择和不选择第 \(i\) 道菜肴。

初始化:\(f(i, j, k) = \begin{cases} 0, j=k=0 \\ +\infty, \text{Otherwise} \end{cases}\)

AC 记录

优化:由于 \(f(i,*,*)\) 只和 \(f(i-1,*,*)\) 有关,所以可以把第一维滚掉,空间复杂度降到 \(O(NX)\)。注意循环要改成倒序。

AC 记录

F - Range Connect MST

题目链接

看到要求最小生成树,首先想到 Kruskal。先回忆一下 Kruskal 的流程:

  1. 将所有边按边权从小到大排序。
  2. 依次遍历所有边。对于每条边,如果它连接的两点不在同一连通块中,则把这条边加入 MST。

对于本题来说,难点在于第二步:边数最多可以达到 \(NQ\),不可能真的遍历每条边。然而,我们真的必须遍历每条边吗?

首先,编号大于 \(N\) 的节点是不重要的,下面我们只关心编号小于 \(N\) 的节点。注意到题目中加边的形式:每次加边都会将 \([L_i, R_i]\) 中的点练成一个连通块。也就是说,如果任意的两点 \(A\),\(B\) 联通,那么所有满足 \(A \le x \le B\) 的点 \(x\) 都和 \(A\),\(B\) 在同一连通块中。

以样例 1 为例,用不同颜色代表不同连通块:

初始时,所有节点互不连通。

\[{\Huge{\color{red}\Box}{\color{green}{\Box}}{\color{blue}\Box}{\color{brown}{\Box}}} \]

第一次操作,把 \(1\),\(2\) 号节点连通:

\[{\Huge[{\color{green}{\Box\Box}}]{\color{blue}\Box}{\color{brown}{\Box}}} \]

第二次操作,把 \(1\),\(2\),\(3\) 号节点所在的连通块连通:

\[{\Huge[{\color{blue}{\Box\Box\Box}}]{\color{brown}{\Box}}} \]

第三次操作,把 \(2\),\(3\),\(4\) 号节点所在的连通块连通:

\[{\Huge{\color{brown}\Box}[{\color{brown}\Box\Box\Box}]} \]

于是可以想到,把边权排序后,对于每次加边操作,从 \(L_i\) 开始,不断跳到当前点所在连通块最右边的(即编号最大)节点(不妨称这个节点的编号为 \(x\)),然后在 \(x\) 和 \(x+1\) 之间连边,直到跳出加边的区间。每次加边的时候,统计一下答案即可。(可以根据上面的图示理解。)以及,别忘了每次操作时,我们还要从编号大于 \(N\) 的节点向编号小于 \(N\) 的节点连一条边(否则不连通),统计答案时记得加上。

连通性显然可以用并查集维护。为了方便快速找到当前连通块最右边的节点,可以直接用最右边的节点作为这个连通块的代表元,这需要在 merge 的时候注意一下参数的顺序(详见代码)。

参考代码

PS:ABC352E 也是一道相似的用 Kruskal 求最小生成树的题,可以去尝试一下。

标签:Box,连通,le,color,题解,菜肴,节点,DEF,ABC364
From: https://www.cnblogs.com/dengstar/p/18329016

相关文章

  • codeforces 1209E2 Rotate Columns (hard version)
    codeforces1209E2RotateColumns(hardversion)题解题目传送门:codeforcces,luogu思路状压dp,贪心。贪心对于所有列,只有列中最大值在所有列的最大值中前\(n\)大才可能对答案有贡献。证明:若有非前\(n\)大的列对某行最大值产生了贡献,则用没有被取的前\(n\)大的列代......
  • Codeforces Round 961 (Div. 2)
    Preface菜的批爆,B2一直WA道心破碎了直接白兰去了,鉴定为纯纯的飞舞本来想着周末补题的然后又摆了一天,E1和E2都没时间补了,鉴定为纯纯的懒狗A.Diagonals签到,贪心枚举即可#include<cstdio>#include<iostream>#include<utility>#include<vector>#include<cstring>#in......
  • 会员购项目面试题解析:高效数据抓取与异常处理
    会员购项目亮点日志记录信息协程异步抓取数据,大大提高抓取速度捕获异常,并添加重试机制源码importloggingimporttimeimportrequestsimportasyncioimportaiohttpfromaiohttpimportContentTypeErrorimportcsv#配置日志logging.basicConfig(level=logging......
  • C++题解(17) 狐猬编程: 640.线段覆盖
    题目描述在一条数轴上,有N条线段,第i条线段的左端点是s[i],右端点是e[i]。如果线段有重叠(即使是端点重叠也算是重叠),则输出“impossible”,如果没有重叠则输出“possible”。输入格式输入文件名:640.in多组测试数据。第一行,一个整数G,表示有G组测试数据。1<=G<=10。每组......
  • [题解]ABC364 A~F
    A-GluttonTakahashi给定\(n\)道菜,每道菜要么是甜的(用sweet表示),要么是咸的(用salty表示)。必须按顺序吃,如果连续吃到\(2\)个甜的菜,就会浑身难受吃不下去了。请问是否能吃完这些菜。按题意模拟即可,只要前\(n-1\)个元素中有连续的sweet就输出No。点击查看代码#include<bits/s......
  • CF292D 题解
    \(O(mk\alpha(n))\)暴力,考虑对于每个询问\(l,r\),枚举\(1\siml-1,r+1\simm\),并查集连边即可。1154ms。\(O(n(m+k\alpha(n)))\)我们发现枚举\(i\in[1,l),j\in(r,m]\)太慢了。考虑先预处理出并查集从\(1\)连边到编号为\(id\)的边的状态\(pre_{id}\),倒过来再处理出......
  • CF626G Raffles 题解
    Description有\(n\)个奖池,第\(i\)个奖池的奖金是\(p_i\),已经有\(l_i\)张彩票押在上面。现在你有\(t\)张彩票,你需要将你的彩票分配到这些奖池中,并且保证你在每个奖池中押的彩票数不能超过该奖池原有的彩票数。若你在第\(i\)个奖池中押了\(t_i\)张彩票,则你中奖的概......
  • CodeForces 1883G1 Dances (Easy version)
    题目链接:CodeForces1883G1【Dances(Easyversion)】思路    为了使得数组a,b中的每个对应元素满足a[i]<b[i],所以将数组a,b按从小到大依次排列,优先删除数组a中较大的元素和数组b中较小的元素,由于删去的元素个数具有单调性,所以使用二分优化,计算最少要删去几个元素。......
  • CodeForces 1883F You Are So Beautiful
    题目链接:CodeForces1883F【YouAreSoBeautiful】思路    要找出一个子数组使得在数组中只能找出一个子序列和当前子数组相等,则只需要找出首元素的数字必须为当前元素值第一次出现,尾元素的数字必须为当前元素值最后一次出现,则只能找出唯一的子序列和当前子数组相等。......
  • codeforces 1209E1 Rotate Columns (easy version)
    codeforces1209E1RotateColumns(easyversion)题目传送门:codeforcces,luogu思路贪心,暴力搜索贪心对于所有列,只有列中最大值在所有列的最大值中前\(n\)大才可能对答案有贡献。证明:若有非前\(n\)大的列对某行最大值产生了贡献,则用没有被取的前\(n\)大的列代替该行......