1 条题解
-
0
E. 美丽数组 – 详细题解
问题重述
给定数组 和整数 。你可以先任意重排数组,然后进行若干次操作:每次选择一个下标 ,令 。目标使数组满足 (即成为回文数组)。求最少操作次数,或输出 表示不可能。
核心观察
- 操作只能将某个元素增加 的整数倍,不能减少。因此元素的值只能在其模 的剩余类中变化(保持 不变)。
- 最终数组必须对称,即对于每对对称位置 ,最终值必须相等。因此这两个位置上的原始元素必须属于同一个模 剩余类,否则无法通过增加 的倍数达到相等(因为模 不同,加 不改变模 )。
- 重排允许我们任意分配元素到最终位置。因此问题转化为:将 个元素分配到 个位置(形成一个对称的配对方案),使得每对对称位置上的两个元素属于同一剩余类,并且通过增加 的倍数使它们相等,总增加次数最小。
按模 分组
将数组元素按 的值分组。设 ,则所有 的元素只能与同余的元素配对,因为对称位置上的两个数必须最终相等,而它们模 必须相同。
可行性条件
每个组内元素个数必须满足:如果 是偶数,则每组元素个数必须为偶数(因为所有元素都必须配对)。如果 是奇数,则有一个位置(中心位置)可以单独放置一个元素(自己与自己对称),因此恰好有一组的元素个数为奇数,其余组必须为偶数。若不符合该条件,则不可能,输出 。
最小操作次数
对于固定的剩余类 ,假设该组内有 个元素(按值排序后为 )。我们需要将它们配对,每对 最终变为同一个值 ,且 ,并且 。由于只能增加( 的倍数),最优策略是让两个数都增加到较大的那个数,或者同时增加到某个更大的值。实际上,若两个数分别为 和 (),则使它们相等的最小操作次数为 (因为每次增加 ,必须使差值被 整除,而同一剩余类保证了 是 的倍数)。总操作次数就是所有配对的 之和。
为了最小化总操作次数,我们应该就近配对:将排序后的元素相邻两两配对(即 , , …)。对于偶数个元素,这是最优的(经典贪心:配对排序后相邻元素)。对于奇数个元素(只能出现在 为奇数的唯一一组),我们需要从中选出一个元素放在中心位置(不参与配对),其余偶数个元素配对。此时需要决定移除哪个元素使得剩余配对的代价最小。
设组内排序后为 ( 为奇数)。移除一个元素 后,剩下 个元素(偶数),按相邻配对,总代价为:
- 对于 左侧(),若长度为偶数,则配对为 , , …;若为奇数,则实际配对方式会改变,但可以通过前缀和快速计算。 更简单的方法:预处理前缀配对的代价和以及后缀配对的代价,然后枚举 ,计算将 作为中心时,左边和右边的配对代价之和。
具体地:
- 定义 :前 个元素( 为偶数)的最小配对代价,即 ,,,依此类推。
- 定义 :从第 个元素到末尾( 为奇数?需要对齐)的配对代价。通常我们定义 为从 到末尾(共 个元素)的配对代价,但要求其长度偶数。为了方便枚举中心,可以预处理后缀配对数组。
常用技巧:计算所有相邻对的差 ()。当 为奇数时,要选出一个元素 作为中心,那么剩下的元素配对方式为:
- 左侧: 个元素,若 为偶数,则配对方式为 ;若为奇数,则配对方式会变成 ,然后多出一个 需要与右侧配对?实际上,移除 后,左右两侧的元素个数分别为 和 ,这两个数必须均为偶数(因为总数为偶数)。因此 和 同奇偶,且和为偶数,所以要么全偶,要么全奇。由于 为奇数, 的奇偶性决定了它们的奇偶性。如果 是奇数,则 和 均为偶数;如果 是偶数,则 和 均为奇数。但偶数个元素可以直接相邻配对,而奇数个元素则不可能(因为剩余元素个数为偶数,要求左右均为偶数)。因此实际上,当 为奇数时,只有 为奇数(即移除奇数位置)才能使左右均为偶数。所以只需枚举 。
此时左侧 有 (偶数)个元素,配对代价为 ;右侧 有 (偶数)个元素,配对代价为 。(注意索引转换)
用前缀和数组 存储:,,,...,即 。后缀和 :,(如果 是奇数?需要保证下标)。实际上,为了统一,我们定义 ()。对于奇数长度组,中心选在第 个元素( 为奇数),则左配对的 下标为 ,右配对的 下标为 (注意下标奇偶性)。可以通过预处理前缀奇 和、后缀奇 和来实现。
更简洁的实现(代码中给出的方法)是:分别计算前缀配对的累计和以及后缀配对的累计和,然后枚举所有可能的中心位置,取最小值。由于 总和不大,可以承受 的计算。
总操作次数
将所有组的最小操作次数相加,即得到总操作次数(注意操作次数是 ,所以最后累加的是差值除以 后的和)。由于代码中累加的是直接的差值(即 ),最后再除以 输出。因此最终答案为 。
特殊情况
- :数组只有一个元素,本身就是回文,操作次数为 。
- 所有元素已经满足回文条件(通过重排可以实现),则答案为 。
算法步骤
- 读入 和数组 。
- 对每个 ,计算 ,将 加入组 。
- 检查奇偶性条件:
- 若 为偶数,则所有组的大小必须为偶数。
- 若 为奇数,则恰好有一组大小为奇数,其余为偶数。否则输出 。
- 对于每个组,将其元素排序。
- 若大小 为偶数,则相邻配对,累加 到 。
- 若大小为奇数(只可能有一个组),则需要枚举哪个元素作为中心(即对称轴),计算除去该元素后的最小配对代价,取最小值加到 中。
- 输出 。
时间复杂度
- 分组:。
- 排序每组:总体 ,因为所有元素总数为 。
- 配对计算:每组线性扫描,总 。
- 满足约束 总和 ,可接受。
正确性说明
- 可行性条件由模 不变性决定:同组才能配对,且中心位置(若 为奇数)允许一个多余元素单独放置。
- 贪心相邻配对在偶数子集中是最优的,因为若将 与 配对(),中间的 必须与其他配对,容易证明交换配对不会使总代价增加。经典结论:将数轴上的点两两配对使总距离最小,就是相邻配对。
- 对于奇数个元素的组,枚举中心位置并取最小配对的代价也是最优的,因为中心元素不参与配对,剩余元素最优配对依然是相邻配对。
因此算法正确。
- 1
信息
- ID
- 6989
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者