You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

大二进制数组三类范围操作需求:寻求支持RangeIntersectQuery的高效数据结构

解决方案:基于有序无重叠区间集合的实现

由于数组规模最大可达109,无法使用常规数组或线段树(内存占用过高),结合你的操作特征(`RangeSet`区间长度仅103),推荐使用有序、无重叠的区间集合维护所有被设置为1的区间(初始状态全为0,0的范围可通过1区间的补集推导),配合二分查找实现所有亚线性时间操作。

核心前提

维护的1区间集合始终满足:

  • 区间按左端点升序排列
  • 区间之间无重叠、无相邻(相邻区间会被合并为一个)

1. RangeSet(v, left, right) 实现

当v=1时(设置区间为1)

  • 通过二分查找,快速定位所有与[left, right)存在交集的1区间
  • 删除这些重叠区间,将它们与[left, right)合并为一个新的区间:[min(left, 所有重叠区间左端点), max(right, 所有重叠区间右端点)]
  • 将合并后的新区间插入集合,维持有序性
  • 时间复杂度:O(logN + K),其中N是当前1区间的数量,K是找到的重叠区间数(因RangeSet区间长度仅10^3,K不会过大)

当v=0时(设置区间为0)

  • 通过二分查找,定位所有与[left, right)重叠的1区间
  • 对每个重叠区间[a, b),拆分出可能的有效子区间:
    • 若a < left,保留[a, left)
    • 若b > right,保留[right, b)
  • 删除原重叠区间,将拆分后的有效子区间插入集合
  • 时间复杂度:O(logN + K),K为重叠区间数

2. RangeIntersectQuery(left, right) 实现

  • 通过二分查找,找到第一个左端点小于right的1区间
  • 遍历后续所有右端点大于left的1区间,计算每个区间与[left, right)的交集:[max(a, left), min(b, right))
  • 收集所有有效交集区间(满足左端点 < 右端点),返回结果列表
  • 时间复杂度:O(logN + M),M为结果区间的数量,远小于N

3. RangeQuery(left, right) 实现

检查区间是否全为1

  • 验证[left, right)是否被1区间完全覆盖:
    1. 通过二分查找定位第一个左端点 ≤ left的1区间,确认其右端点 ≥ left
    2. 依次遍历后续区间,检查每个区间的左端点是否等于前一个区间的右端点,且最终覆盖到right
    3. 若所有覆盖区间的并集恰好等于[left, right),返回true,否则返回false
  • 时间复杂度:O(logN + K),K为覆盖所需的区间数

检查区间是否全为0

  • 通过二分查找判断是否存在1区间与[left, right)重叠:
    1. 找到第一个左端点 > left的区间,检查其左端点 < right
    2. 同时检查前一个区间(若存在)的右端点 > left
    3. 若两种情况都不成立,说明无重叠,返回true;否则返回false
  • 时间复杂度:O(logN)

实现细节

  • 可以用语言自带的有序集合实现(如Python的bisect模块维护有序列表,C++的std::set),快速完成二分查找、插入、删除操作
  • 所有操作均为亚线性时间,完全满足你的性能要求

内容的提问来源于stack exchange,提问作者G.M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 16:22:42