1 条题解
-
0
题目回顾
维护一个初始包含 个不同整数的集合,支持三种操作:
- 插入元素 (保证 不在集合中)
- 删除元素 (保证 在集合中)
- 查询 -负载:最小的正整数 ,使得 都不在集合中
约束:所有测试用例的 总和 , 总和 ,元素值 。
问题转化
-负载的定义:最小的 ,使得长度为 的连续整数区间 完全不在集合中。
换句话说,我们要找所有不在集合中的连续整数区间,并找到其中长度 的区间,取这些区间的左端点的最小值。
设集合为 ,则“不在集合中的连续整数区间”就是正整数轴上被 分割出的“空段”。例如 ,正整数轴上的空段为:
- (长度 )
- (长度 )
- (长度 )
- (无穷长,可视为长度无穷大)
对于 ,长度 的空段有 和 ,最小左端点是 ,即 -负载。
核心思路
1. 维护空段(free segments)
用
std::set<int> M维护当前集合中的所有元素(有序)。空段可以表示为半开区间 ,其中 和 都是集合中相邻的元素(或边界 和 ):- 若 (已排序),则空段为:
- 对
注意 是一个无限长的空段,处理时用一个大数 代替 (例如 足够)。
插入 时:
- 找到 在 中的前驱 和后继 。
- 原来的空段 被 拆分成两个空段: 和 。
- 删除原空段,插入两个新空段。
删除 时:
- 找到 在 中的前驱 和后继 。
- 原来的两个空段 和 合并成一个空段 。
- 删除这两个空段,插入合并后的空段。
2. 查询 -负载
我们需要在所有空段中,找到长度 的那些空段,并输出它们的最小左端点。
空段可以用二元组 表示。对于无限长空段,长度设为 (足够大)。
查询 时,等价于在所有长度 的空段中,找最小左端点。
数据结构设计
用笛卡尔树维护空段
对每个空段 建立一个节点。节点的键值对为 ,按键值排序(先按长度升序,长度相同时按左端点升序)。
笛卡尔树性质:节点的优先级(随机)满足堆性质,键值满足 BST 性质。
我们需要快速支持:
- 插入/删除一个节点(对应空段的插入/删除)
- 查询所有键值 的节点中的最小
节点信息
每个节点存储:
key:prior:随机优先级minl:子树中所有节点的 的最小值
upd(v)维护minl = min(v.key.l, minl(lv), minl(rv))。查询操作
查询 时,我们想找到所有长度 的节点。
由于键值按 排序,长度 的节点在 BST 中正好对应一个后缀:所有键值 的节点(因为 ,用 确保包含所有长度为 的节点)。
所以:
- 用
split(root, (k, -1))将树分成两部分:s1:键值 的节点(长度 )s2:键值 的节点(长度 )
- 答案 =
- 因为无限长空段 的左端点是 ,需要与有限空段的最小左端点比较。
- 合并回
root = merge(s1, s2)。
特殊情况:集合为空时,整个正整数轴都是空段,-负载就是 。
复杂度分析
- 每个插入/删除操作: 用于在
std::set中找前驱后继, 用于笛卡尔树的 split/merge/删除。 - 每个查询操作: 用于 split 和 merge。
- 总复杂度:。
关键实现细节
- 边界处理:用 表示左边界 的前驱,用 表示右边界无穷大。
- 无限长空段:在
add_val和rem_val中,当 时,不添加右边界为无穷的空段(实际上它一直存在,但查询时会用*M.rbegin()+1兜底)。 - 内存管理:预分配一个大数组
mem作为节点池,避免动态内存分配开销。 - 随机优先级:使用
mt19937保证树的平衡性期望 。
示例推导
以样例第一个测试用例的部分操作为例:
初始集合 ,空段:
- (长度 )
- (长度 )
- (长度 ?注意是到 之前)
- (无限长)
查询 :长度 的空段中最小左端点是 ?但答案输出第一个
? 2结果是 ?实际上集合中 和 存在,所以 不是空段,最小长度 的空段左端点是 吗?再检查: 左端点是 ,但 被占用了,所以 时 有 在集合中,不行; 时 有 在集合中,也不行; 时 两个都不在集合中? 和 都不在,确实 的负载是 ?但样例输出第一个? 2是 !说明我理解有误。重新理解:样例第一个测试用例在第一个
? 2之前执行了- 2,删除 后集合为 。空段:- :包含 ,长度 ,左端点 。
- ,,。
:长度 的空段中最小左端点是 。所以答案是 。正确。
总结
本题的核心是将 -负载问题转化为“找长度 的空段的最小左端点”。使用:
std::set维护集合元素,用于快速定位空段边界。- 笛卡尔树(Treap)维护空段,按长度排序,支持 的插入、删除、后缀最小值查询。
这种方法巧妙地利用了笛卡尔树的 split 操作,将“长度 ”的条件转化为树上的后缀分割,从而高效地回答查询。
- 1
信息
- ID
- 6306
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者