1 条题解
-
0
C. 冒险家 详细题解
问题重述
平面上有 个点(可能重合)。要选择一个分割点 ,将平面分成四个象限(包含边界):
- 第一象限(含右、上边界):
- 第二象限(含左、上边界):
- 第三象限(含右、下边界):
- 第四象限(含左、下边界):
记四个象限内的点数分别为 。目标:最大化 ,并输出任意一个达到该最大值的 。
核心观察
- 最优的 可以取在某个点的 坐标处(或稍向左/右),因为移动 只改变点在左右的分组,且只有在穿过点的 坐标时才会改变计数。同样 可以取在某个点的 坐标处。
- 因此,我们可以枚举可能的 (所有不同的 坐标),然后对于每个 ,快速找到最优的 使得 最大。
- 问题转化为:给定一个垂直线 将点分为左右两部分,我们需要在 轴上找一个分割点 ,使得四个象限的点数都不小于某个值 。
二分答案
显然答案 满足 ,且可以二分。假设我们判断是否存在 使得四个象限的点数都 。
固定 ,对于每个可能的 (即所有点的 坐标),我们检查是否存在 满足:
- 左侧部分()中, 的点数 且 的点数 ;
- 右侧部分()中, 的点数 且 的点数 。
由于左右两部分独立,我们可以分别求出每个部分中 的可行区间,然后判断是否有交集。
数据结构维护
对 坐标离散化后,我们可以用线段树维护点数的前缀和。但这里需要支持动态删除左侧的点(当 向右移动时)。
算法流程:
-
将所有点按 坐标排序。
-
预处理一个数据结构(如 Fenwick 树或线段树)存储所有点的 坐标计数,初始时包含所有点(对应 为最左侧的情况)。
-
枚举 的取值(所有不同的 坐标,按升序):
- 当前数据结构中存储的是 的点(右侧部分)。左侧部分就是已经移除的点。
- 对于当前右侧部分的 分布,我们可以通过线段树查询得到:对于任意 ,右侧部分中 和 的点数。类似地,左侧部分我们也可以用一个额外的数据结构(或者维护前缀和)来查询。
- 我们需要找到 使得左右两侧的上下计数都 。这等价于:左侧部分中, 必须落在某个区间 内(即左侧部分的累积分布函数满足要求);右侧部分中, 必须落在区间 内。如果两个区间有交集,则存在可行的 。
- 为了快速得到这些区间,可以在线段树上进行二分(或递归下降)。标程中的
FindBest函数正是做这件事:它在线段树上递归,同时维护左右两侧的计数,最终找到使最小点数最大的 ,并返回该最大最小值。
-
当 向右移动到下一个值时,将当前 坐标上的所有点从右侧数据结构中删除(并添加到左侧的计数中)。
复杂度
- 排序 。
- 对于每个不同的 坐标,需要 的时间在线段树上找到可行区间(或最优 )。
- 总复杂度 (因为二分答案外层还有一个 ),但标程直接在一个扫描中同时找到了最大 ,不需要外层二分,实际实现为 或 。由于 ,可接受。
标程解析
标程中的关键数据结构:
Tree是动态开点的线段树,每个节点维护一个Count结构,包含left和right两个整数,表示在该节点对应的 区间内,小于当前分割点(递归过程中临时设定的 )的点数和大于等于当前分割点的点数。递归函数FindBest不断下探,最终得到最优的 和对应的最小象限点数。- 扫描过程中,维护一个全局的
Tree,初始包含所有点。随着垂直线右移,将左侧的点从树中移除(Remove操作)。每次移除一批点后,调用FindBest更新答案。
该实现巧妙地同时处理了左右两侧的计数,因为左侧的点已经被移除,而
FindBest在递归时通过参数left和right传递了左侧部分在当前 区间内的点数,从而实现了左右合并。
算法步骤总结
- 读入所有点,按 排序。
- 建立动态开点线段树,将所有点的 坐标插入。
- 初始化答案 ,最优坐标 。
- 从左到右扫描不同的 值(即所有点的 坐标):
- 调用
FindBest函数,在当前线段树(代表右侧部分)中递归寻找最优水平分割线,同时通过传递的左右计数参数得到左侧部分的信息,计算出当前 下能达到的最大最小象限点数 。 - 如果 ,更新 和 。
- 然后将当前 坐标上的所有点从线段树中移除(相当于将它们划归左侧)。
- 调用
- 输出 和 。
复杂度
- 线段树节点数 ,其中 是 坐标值域大小(使用动态开点,实际节点数约 ,)。
- 每个点插入和删除一次,每次 。
FindBest每调用一次 。- 总复杂度 ,在给定约束下可以接受。
参考代码(标程已提供)
标程的代码即为本题的正解,使用动态开点线段树和递归搜索实现。可直接使用。
总结
本题的核心在于将二维问题转化为一维扫描,利用线段树维护 方向上的分布,并通过递归搜索快速找到最优水平分割线。二分答案可省略,因为扫描过程中自然就能得到最大 。
- 1
信息
- ID
- 7179
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者