Codeforces Round 1044 (Div. 2) A-E题解

Problem - A - Codeforces

题意概括:给你一个长 \(n\) 的正整数数组 \(a\) ,你可以任意改变元素顺序。之后,定义一个 \(z=1\) , 遍历 \(2\le i\le n\) ,每一步会使 \(z:=z\times \frac{a_{i-1}}{a_i}\) ,你需要判断是否有一种顺序使得最后 \(z=1\)

范围:\((1\le n,a_i \le 100)\)

题解:我们发现,对于 \(2\le i \le n-1\) 的元素,它们在总表达式中会被当成分子 \(1\) 次,被当成分母 \(1\) 次,也就是说,我们可以完全忽略这些下标的元素的贡献,只看 \(i=1\)\(i=n\) 就好了。最后表达式实际上就是 \(z\times \frac{a_1}{a_n}\) ,那么让 \(a_1=a_n\) ,也就是说数组中有 \(2\) 个或者以上相等的数字即可。

实现:记录 \(1\) 个数组,使其记录数组 \(a\) 中每个数值的元素数量,一旦有一个数值的元素数量大于等于 \(2\) ,输出 \(YES\) ,否则输出 \(NO\)

Problem - B - Codeforces

题意概括:给你 \(n\) 个点,每个点都有一个点权 \(g_i\) ,你可以选择 \(2\) 个点 \(i,j\) 并在它们之间建立 \(1\) 条无向边,代价是 \(max(g_i,g_j)\) ,之后,这 \(2\) 个点的点权都减去 \(min(g_i,g_j)\) ,你需要让这些点连接成 \(1\) 个连通分量,求所需的最小代价。

范围:\((1\le n\le 2\times 10^5,1\le g_i\le 10^9)\)

题解:我们从大往小考虑,最大的那个点如果要与其他点相连,代价一定是最大的那个点的点权。然后使与它相连的那个点的点全变为 \(0\) 我们当然要找第 \(2\) 大的点相连最优。这时,最大点和次大点相连,而次大点的点权变为 \(0\) ,这两个点就等效于一个点权为 \(0\) 的点了,然后丢掉这 \(2\) 个点不看,剩下的所有点也找最大和次大相连,以此类推,我们最后会得到一堆点权 \(0\) 的点,让它们相连就好。(如果 \(n\) 为奇数会多一个最小值,直接连就好,不影响)。

实现:排序,然后 \(i\)\(n\) 遍历到 \(1\) ,每次跳 \(1\) 个值,记录和就好。

Problem - C - Codeforces

题意概括:(交互题)给你一个有向无环图大小 \(n\) ,你可以这样询问最多 \(2n\) 次:

\(?\) \(i\) \(k\) \(a_1\) \(a_2\) \(...\) \(a_k\)

系统会告诉你在大小为 \(k\) 的点集合 \(a_1,a_2...a_k\) 中,以点 \(i\) 为起点的最长路径长度。

你需要输出这个图的最长路径长度并按顺序给出其中 \(1\) 条路径上的点。

范围:\((1\le n\le 500)\)

题解:我们要知道,在 \(1\) 条最长路径上的点,以它们为起点的最长路径是连续的,也就是说,假设有一组最长路径是 \(1->4->2->3\) ,那么如果询问以每个点为起点,在全集中的最长路径,结果一定是 \(1:4,4:3,2:2,3:1\),那么接下来就很简单了。只需要找到一个最长路径的起点 \(d\) ,假设最长路径长度是 \(ma\) ,那么在询问全集最长路径为 \(ma-1\) 中找到一个 \(d\) 能到的点,然后将其记为 \(d\) ,继续找 \(d\) 能到的 \(ma-2\) 的点,以此类推,过程就是答案。

实现:对于每个点 \(i\) ,先询问 \(?\) \(i\) \(n\) \(1\) \(2\) \(...\) \(n\) ,记得到的值为 \(z\) ,以 \(z\) 的大小为标准做一个二维链表 \(vector<vector<int> >\) ,然后记录二维链表中存在有值的最大下标 \(z_{max}\) 然后遍历 \(i\)\(z_{max}\)\(1\) ,按题解的方法进行就好。

Problem - D - Codeforces

题意概括:给你一个长 \(n\) 的正整数数组 \(a\) ,你可以进行下列操作任意次:

  1. 花费 \(1\) 代价选择 \(1\) 个下标 \(i\) ,使得 \(a_i=a_i-1\) ,之后执行操作 \(2\)
  2. 若存在 \(a_i\le 0\) ,以 \(a_i\) 为分界线将原数组变为两个数组,然后,后面的那个数组的第 \(1\) 个元素减去 \(i\) 并重新执行操作 \(2\)

你需要给出让所有元素都变成非正整数的最小代价。

范围:\((1\le n\le 2\times 10^5,1\le a_i\le 10^9)\)

题解:想要最大程度上减少代价,必须让操作 \(2\) 的作用最大化。

先来从后往前分离数组(这个意思就是,从后往前这样做:将原数组 \(a\) 中的一个下标的元素消去,使得后面那个数组变为数组 \(b\)),这个 \(b\) 有什么性质呢?

首先,这个 \(b\) 不可分,只能从前往后依次删数。为什么?因为假设 \(b\) 再进行分离操作得到 \(c\) ,这样的操作比 \(b\) 从头到尾删数更优,那么我为什么不一开始就把这个 \(c\) 当作 \(b\) 呢?

所以,我们会在原数组 \(a\) 上,假定分离出 \(b\) 需要删去的元素下标是 \(i\) ,那么以 \(i\)\(n\) ,操作 \(2\) 的作用就是 \(0\) \(min(i,a_i)\) \(1\) \(1\) \(...\) \(1\)

整个数组 \(a\) 中,操作 \(2\) 的作用对于下标就是 \(0\) \(1\) \(1\) \(...\) \(1\) \(0\) \(min(i,a_{i+1})\) \(1\) \(1\) \(...\) \(1\) (因为操作 \(2\) 的作用不能超过数本身)。

之后,分离出了这个 \(b\) ,我们当然可以从 \(i-1\) 开始继续分离数组,结果一定是 \(0\) \(1\) \(1\) \(...\) \(1\) \(0\) \(min(i,a_{i+1})\) \(1\) \(1\) \(...\) \(1\) \(0\) \(min(j,a_{j+1})\) \(1\) \(1\) \(...\) \(1\) 什么的。

在数值上,我们可以发现,事先假设不分离数组然后从头到尾删数,操作 \(2\) 的作用为 \(0\) \(1\) \(1\) \(...\) \(1\) ,也就是说,只要选择一个下标 \(i\) 删除以分离数组,那么操作 \(2\) 的作用一定是将对 \(i\) 的作用变为 \(0\) ,然后将对 \(i+1\) 的作用变成 \(min(i,a_{i+1})\) ,其他的不变。

这不就是动态规划吗,让作用最大就好了。

实现:动态规划 \(dp_{i,j}\) 为遍历到第 \(i\) 个数,是否选择该数的上一个下标 \(i-1\) 删除 \(j\),得到的最大值 \(dp_{i,j}\)

\(2\) 开始遍历到 \(n\)

初始化,\(dp_{1,1}=dp_{1,0}=0\)

转移方程:\(dp_{i,1}=dp_{i-1,0}+min(i-1,a_i)-(i!=2)\);

\(dp_{i,0}=max(dp_{i-1,1},dp_{i-1,0})+1\)

Problem - E - Codeforces

题意概括:给你一棵大小为 \(n\) 的树,上面有个 \(Him\) ,一开始, \(Him\) 可能在树的任意位置,你可以进行以下操作总和不超过 \(\lfloor \frac{5}{4}n \rfloor\) 次以保证最后一定能抓住 \(Him\)

  1. 短暂照亮 \(1\) 个点,如果此时 \(Him\) 在这个点上或者接下来移动到这个点上,\(Him\) 就会被抓住。然后,\(Him\) 移动到一个相邻的点或者不移动。
  2. 删除与 \(1\) 个点有关的所有边,然后,\(Him\) 移动到一个相邻的点或者不移动。

保证一定有方案抓住 \(Him\)

范围:\(1\le n\le 2\times 10^5\)

题解:首先,操作 \(1\) ,显然可以抓住在 \(1\) 条链上的 \(Him\) ,从一端到另一端就好了,因为 \(Him\) 可能在树的任意一个地方,所以操作 \(1\) 必须在所有连通分量都为链的情况下进行 \(n\) 遍。更具体的说,我们要在 \(\lfloor \frac{1}{4}n \rfloor\) 次操作 \(2\) 下把所有连通分量都变成链。怎么办呢?

假设我们以某个点为根,定义一个点是有效子节点,仅在这个点和它的子树还有它的父节点能组成链。

(注意,在遍历的同时会进行删边操作,所以有效子节点的定义是动态的)

那么接下来,对于任意一个点,以它的有效子节点数量 \(c\) 做如下区分:

\(c\le 1\) :这个点及其有效子树组成一个链,那么对这个点的父节点来说,它是一个有效节点。

\(c=2\) :这个点有 \(2\) 个有效子节点,这时,强制对它的父节点进行操作 \(2\) (如果有的话),它和它的子树成链,它不是一个有效节点。

\(c>2\) :这个点的有效子节点至少为 \(3\) ,那么直接对它进行操作 \(2\) ,它不是一个有效节点。

如此操作一定能把树变为一堆链,下面证明次数合法。

对于 \(c=2\) 的操作 \(2\) ,因为这个点、这个点的 \(2\) 个子节点,这个点的父节点,合起来一共是 \(4\) 个节点。那么操作 \(2\) 后,相当于从原树上删去了至少 \(4\) 个节点,所以次数一定合法。

对于 \(c>2\) 的操作 \(2\) ,这个点、这个点的至少 \(3\) 个子节点,合起来也是 \(4\) 个节点,相当于从原树上删去了至少 \(4\) 个节点,所以也合法。

模拟即可。

实现:第一遍 \(dfs\) ,模拟该操作删边,第二遍 \(dfs\) ,找度小于等于 \(1\) 的点做子 \(dfs\) ,遍历完所有点。

posted @ 2025-08-25 15:51  Vsg21  阅读(45)  评论(0)    收藏  举报