1 条题解
-
0
题意回顾
我们有 条线段 。
一个线段集合是 复杂的,当且仅当它能被划分为若干个子集,使得:- 所有子集的大小相同,记为 ;
- 两条线段相交 它们属于同一个子集。
换句话说,每个子集内部两两相交,不同子集之间两两不相交。
目标:从给定的 条线段中选出一个最大的子集(记其大小为 ),使得这个子集是复杂的。输出 。
问题重述
设我们最终选出的子集有 组,每组 条线段,则 。
这 组之间互不相交(因为不同组的线段不能相交),但组内任意两条都相交。也就是说,每一组是一个 团(clique)在相交关系图中,且不同团之间无边。
第一步:固定 ,求最大
如果固定每组的大小为 ,问题变成:
在 条线段中,最多能选出多少个互不相交的团,每个团大小恰好为 ?因为不同团之间不能有边,所以这些团是 边不交 的(即线段互不相交)。
而且同一个团内的所有线段必须两两相交,这意味着团内所有线段的交集非空。性质
一个大小为 的团,其交区间非空,等价于存在一个点 ,使得这 条线段都包含 。
所以我们可以把问题看作:找 个互不相交的 (每个 对应一个团),每个 覆盖恰好 条线段。更精确地说:
我们按 排序,扫描时维护一个数据结构,标记哪些线段还未被分配。
当发现一个点 被至少 条未分配的线段覆盖时,我们就从中任意选 条组成一个团,并移除它们。
算法实现(固定 )
- 将线段按 升序排序,保证处理时右端点单调。
- 初始化一个数组 ,表示当前未分配的线段中,覆盖点 的数量。
- 遍历每条线段(按 顺序):
- 把当前线段标记为“活跃”(未分配)。
- 在 区间上, 每个位置 。
- 如果某个位置 的 ,说明可以形成一个团:
选择覆盖 的任意 条线段(包括当前这条),移除它们(对应 减 ),并增加 。
- 最终 就是最多能形成的团数。
这个过程的难点在于:如何快速找到第一个 的位置?
优化
- 用线段树维护 数组,区间加 和查询最大值的位置。
- 找到后,需要找到覆盖 的 条线段并移除。
移除意味着将这些线段从活跃状态删除,对 的影响是:对于每条被移除的线段 , 在 上减 。
但注意:移除的线段可能还未被遍历到(即它们的 大于当前扫描的 )。
实际上,我们可以在扫描时维护一个“已分配”的线段集合,但这样复杂度会高。
官方解法中的技巧
他们用一个二进制字符串维护“哪些线段是当前活跃的”,但更关键的是:
当找到一个点 满足 时,这 条线段一定包含当前正在处理的线段(按 顺序)。
所以只需移除当前线段以及之前的一些未分配线段(按 排序即可找到)。实现细节:
- 维护一个 DSU(并查集),快速找到左边第一个未分配的线段。
- 移除时,更新覆盖计数(用区间减 ),但不需要显式维护 数组,而是维护“后缀最大值”的变化。
最终复杂度: 对于固定 。
第二步:遍历所有可能的
我们需要最大化 。
注意到 。
对于常数 ,要么 ,要么 。取 ,则:
- 当 时,枚举 ,每个 用 计算最大 ,复杂度 $O(C \cdot n \alpha(n)) = O(n^{1.5} \log^{0.5} n \cdot \alpha(n))$。
- 当 时,枚举 ,每个 用二分法找最大 (因为 越大 越小),二分内调用 的判断,复杂度 $O((n/C) \cdot \log n \cdot n \alpha(n)) = O(n^{1.5} \log^{1.5} n \cdot \alpha(n))$。
取 平衡两者,总复杂度 。
第三步:最终算法总结
- 排序所有线段按 升序。
- 对于每个 从 到 :
- 用 DSU + 扫描法计算最大 ,更新答案 。
- 对于每个 从 到 :
- 二分查找最大 使得 可行,更新答案。
- 输出 。
时间复杂度
- 固定 的扫描:,其中 是反阿克曼函数。
- 总复杂度 ,足以通过困难版。
代码框架(伪代码)
def max_k(m, segments): # segments 按 r 排序 # 维护 DSU 表示下一个未分配的线段 # 扫描 r 递增 # 每次发现一个点覆盖 >= m 条未分配线段时,移除 m 条 return k def solve(): sort segments by r ans = 0 C = int((n * log(n))**0.5) for m in 1..C: k = max_k(m) ans = max(ans, m * k) for k in 1..(n // C): # 二分 m lo, hi = 1, n // k while lo <= hi: mid = (lo+hi)//2 if max_k(mid) >= k: lo = mid+1 else: hi = mid-1 ans = max(ans, k * hi) print(ans)
- 1
信息
- ID
- 6283
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者