Codeforces Round 1040 (Div. 2) A-E2 题解

  1. Problem - A - Codeforces

    题意概括:给你一个非负整数集合 \(T\) ,在这个集合不为空时,你可以选择任意个元素,然后选择下列操作之一执行:

    ​ 将答案增加所选元素的 \(mex\)

    ​ 将答案增加所选元素的 \(sum\)

    求答案的最大值。

    题解:贪心考虑,选择 \(mex\) 大于等于 \(sum\) 的元素只有 \(0\)\(0,1\) ,其中 \(0,1\) 可以视为 \(mex(0)+sum(1)\) ,也就是说,只选择对 \(0\) 使用 \(mex\) ,对其他元素使用 \(sum\) 即可使答案最大。

  2. Problem - B - Codeforces

    题意概括:你需要重新排序一个长 \(n\) 仅包含 \(0,1,2\) 且每种至少有 \(1\) 个的序列,使得对于每一条起点为 \(1\) ,终点为 \(n\) 的路线经过的点权值加起来不能等于 \(m\)

    题解:这里 \([1,n]\) 表示直接从 \(1\) 走到 \(n\) 经过的点权值。

    先考虑所有路线的特性,显然是除了正常的从 \(1\) 直接走到 \(n\) 以外,还能多次经过所有大于 \(1\) 的连续区间,也就是说,只需要使得题目给的 \(m\) 无法被 \([1,n]+\) 若干区间和 表示即可。

    那么我们讨论区间情况,如果一个 \(0\)\(1\) 相邻,那么总是能走出大于等于 \([1,n]\) 的所有值(可以一直 \(010101\) 粪招复读),也就是说,我们最好不让 \(0\)\(1\) 相邻,那么就会发现,这时的序列一定是 \(0\)\(2\) 相邻,\(1\)\(2\) 相邻,\(1\)\(1\) 相邻,\(2\)\(2\) 相邻,\(0\)\(0\) 相邻。仅说走过这些相邻区间,相当于 \(+2,+3,+2,+4,+0\) ,这些有用的就只有 \(+2,+3\) ,熟悉质数的朋友们都知道,这两个数字能够组合成除了 \(1\) 以外的所有正整数。

    也就是说,只有 \(m<[1,n]\) 或者 \(m=[1,n]+1\) 才能用上述构造满足题意,其他的输出 \(-1\) 即可。

  3. Problem - C - Codeforces

    题意概括:给你 \(n\) 个保证右端点严格大于左端点的区间,你需要选择其中的任意一个集合 \(S\)。这里:

    \(f(S)\) 表示集合中所有区间视为一条左端点到右端点的无向边后,构成大于等于三元环的所有点集合大小。

    \(g(S)\) 表示集合中所有区间的并区间,满足 \(c\)\(c+1\) 都在这个并区间的 \(c\) 的数量。

    你需要最大化 \(g(S)-f(s)\) 的值。

    题解:我们有一种方法,选择区间使得并区间最大且使得 \(f(S)=0\)

    设区间为 \([l,r]\)

    首先直接考虑怎样会形成三元环(及以上),最小限度应当是选择 \([a,b],[b,c],[a,c]\) ,显然,形成三元环的条件之一就是选择两个 \(l\) 相同的区间,但是,要保证 \(g(S)\) 最大的话,相同的 \(l\) 选择不同的 \(r\) ,对于 \(r\) 比较小的那个是没有意义的,也就是说,对于每个 \(l\) ,选择最大的 \(r\) 即可。

    排序模拟即可。

  4. Problem - D - Codeforces

题意概括:给你一个长 \(n\) 的排列 \(a\),你可以选择其中的任意数量的元素 \(a_i\),使其变为 \(2n-a_i\)

你需要使得最后排列的总逆序对数最小。

题解:这里考虑变化 \(1\) ,显然,变化 \(1\) 之后,它一定是全数组最大的那个数(即使其他数也变化),也就是说,变化其他任何数都不会使得关于 \(1\) 的逆序对数量发生变化,对于 \(1\) 是否变化,我们只需要考虑变化前后关于 \(1\) 的逆序对数量变化是否有益即可。

同时,因为之后的任意变化都不会改变关于 \(1\) 的逆序对数量(即使 \(1\) 不发生变化),之后考虑 \(2\) 的时候,我们就可以直接在 \(a\) 中去除 \(1\) 来考虑,这时 \(2\)\(a\) 中最小的数字,我们当然可以把上述对 \(1\) 的考虑放在 \(2\) 上面。

然后以此类推即可。

  1. Problem - E1 - Codeforces

    题意概括:给你一个括号序列 \(S\) 的长度 \(n\) \((2\leq n \leq 1000)\),然后你可以这样询问最多 \(550\) 次:

    \(?\) \(k\) \(a_1\) \(a_2\) \(a_3\) \(...\) \(a_k\) \((k\leq 1000)\)

    会回答你字符串 \("S_{a_1}S_{a_2}S_{a_3}...S_{a_k}"\) 的正则括号子串的个数。

    保证这个括号序列至少有一个 \('('\) 和一个 \(')'\)

    你需要在询问次数范围内给出这个括号序列是什么。

    题解:找到了一对确定的 \(()\) 这道题就好做了,所以我们先找一对 \(()\)

    因为至少有一个 \('('\) 和一个 \(')'\) ,所以对整个串进行询问,如果结果为 \(0\) ,那么一定有 \(S_1=')',S_n='('\)

    如果结果不为 \(0\) ,那么这个串内一定有一个 \(i\) 满足 \(S_i='(',S_{i+1}=')'\) ,这里我们二分查找最大的 \(i\) ,使得包括这个 \(i\) 的后缀的询问结果不为 \(0\) ,这时的 \(i\) 就是满足 \(S_i='(',S_{i+1}=')'\)\(i\)

    然后观察 \(550\) 次这个限制,可以发现我们的每次询问必须能询问出括号序列中起码 \(2\) 个位置。也就是说,我们必须构造一种询问方式,使得对于 \(2\) 个位置所会发生的所有情况询问都有不同的结果。

    这个构造很痛苦,我构造出来的是给这两个位置的元素的前面加上 \(((()()\) ,这样,根据这两个位置的不同得到的结果分别为 \(3,4,5,6\)

    询问单个位置的很简单,就不讲了。

    模拟即可。

  2. Problem - E2 - Codeforces

    (请注意!我的解法和现在的正常解法有偏差,使我被 \(E3\) 丹砂)

    题意概括:询问最多 \(200\) 次。

    题解:只有询问次数的变化,那么我们只需要每次询问处理 \(6\) 个位置即可。

    因为会返回 \(3,4,5,6\) ,所以可以构造多个关于 \(2\) 个位置的询问,比方说需要询问 \(6\) 个位置时,可以直接使第 \(1\)\(2\) 的新元素的询问重复 \(7\times 7\) 次,第 \(2\) 组重复 \(7\) 次,第 \(3\) 组重复 \(1\) 次,这样得到一次询问的结果可以转化为三个询问的结果。

    模拟即可。

posted @ 2025-08-02 15:01  Vsg21  阅读(52)  评论(0)    收藏  举报