Codeforces Round 1044 (Div. 2) A-E题解
题意概括:给你一个长 \(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\)。
题意概括:给你 \(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\) 个值,记录和就好。
题意概括:(交互题)给你一个有向无环图大小 \(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\) ,按题解的方法进行就好。
题意概括:给你一个长 \(n\) 的正整数数组 \(a\) ,你可以进行下列操作任意次:
- 花费 \(1\) 代价选择 \(1\) 个下标 \(i\) ,使得 \(a_i=a_i-1\) ,之后执行操作 \(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\)
题意概括:给你一棵大小为 \(n\) 的树,上面有个 \(Him\) ,一开始, \(Him\) 可能在树的任意位置,你可以进行以下操作总和不超过 \(\lfloor \frac{5}{4}n \rfloor\) 次以保证最后一定能抓住 \(Him\):
- 短暂照亮 \(1\) 个点,如果此时 \(Him\) 在这个点上或者接下来移动到这个点上,\(Him\) 就会被抓住。然后,\(Him\) 移动到一个相邻的点或者不移动。
- 删除与 \(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\) ,遍历完所有点。
浙公网安备 33010602011771号