1 条题解
-
0
自动搬运
来自洛谷,原作者为

MightZero
Connector & Unattainable Sun Day.搬运于
2025-08-24 23:05:01,当前版本为作者最后更新于2024-10-17 12:35:01,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
原问题直接做显然是不好处理的,考虑做如下转化:给定一个指定的内存段(即题目条件中 所表示的内存段),每次选择一个所有元素都相同的合法序列并修改整个序列为某个值,求将整个内存段修改为全 的最小操作次数。由于修改为 在最优方案中必然是在最后一步修改整个内存段,因此只需要考虑将将整个内存段所有元素修改为相同值所需要的最小操作次数。
注意到题目给出的合法区间本质上可以看作一棵范围 的线段树的某个节点,考虑建线段树;但是树的深度比较大,需要动态开点。建树时将每个 对应的区间插入线段树即可。
对于每个线段树上的节点,可以维护一个集合 表示在最优操作次数下将当前节点对应区间所有元素修改为相同值时,这一相同值所有可能的取值;
遍历整棵线段树,考虑如何合并节点的左右儿子的 :
-
若 ,那么必须修改其中一个儿子对应区间的值才能满足条件,此时将 ;由于可以将一个儿子的值修改为另一个儿子取值集合中的任意元素,最终可能的取值集合
-
若 ,此时不需要修改, 不变,。
说明:若某个节点 处 ,这个节点的儿子可以修改也可以不修改;但是本题中需要考虑的是最小操作次数,如果这一结点的某个祖先 处必须修改,即 ,注意到在 处修改儿子对于在 处修改儿子是必然不劣的,因此只在必须修改的时候修改儿子可保证答案最优。
具体实现上可以使用
std::set或者std::vector维护集合,输出 时记得 。 -
- 1
信息
- ID
- 10874
- 时间
- 1500ms
- 内存
- 500MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者