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

数组区间查询:求0~L中大于A[R]的元素和的高效解法问询

解决方案:前缀区间内大于指定值的元素和查询

针对问题中1≤N,Q≤10⁵的规模,以下是几种高效的实现方案,覆盖离线、在线两种场景:

一、离线处理 + 树状数组(最优解)

这是时间复杂度最优的方案,适合可以离线收集所有查询的场景。

核心思路

通过将查询按L从小到大排序,逐步将数组元素加入树状数组,确保处理每个查询时,树状数组恰好包含0~L的所有元素。利用树状数组快速计算≤A[R]的元素总和,用前缀总总和减去该值即可得到大于A[R]的元素和。

具体步骤

  1. 预处理查询:将所有查询存储为三元组(L, R, idx),其中idx记录原查询的序号,用于最后按原顺序输出结果。
  2. 排序查询:将查询按L升序排列。
  3. 初始化数据结构:维护两个树状数组:
    • sum_tree:维护对应值的元素总和,支持单点更新和前缀查询。
    • cnt_tree:维护对应值的元素个数(可选,也可直接用sum_tree查询最大值得到总总和)。
  4. 遍历处理:
    • 用指针ptr标记当前已加入树状数组的元素范围(初始为0)。
    • 对每个排序后的查询:
      • 若ptr ≤ L,将A[ptr]插入树状数组(sum_tree添加A[ptr],cnt_tree添加1),并将ptr递增,直到ptr > L。
      • 计算0~L的总元素和:total = sum_tree.query(100000)(因A[i]≤1e5)。
      • 计算≤A[R]的元素和:less_sum = sum_tree.query(A[R])。
      • 当前查询的答案为total - less_sum,存入结果数组的idx位置。
  5. 输出结果:按原查询顺序输出结果数组。

复杂度分析

  • 时间:O((N+Q)logM),其中M是A[i]的最大值(1e5),完全满足1e5规模的性能要求。
  • 空间:O(M),树状数组的空间开销为1e5级别,可接受。

离散化适配

若A[i]范围超过1e5(如1e9),需先对所有A[i]和查询中的A[R]进行离散化,将值映射到1~K的范围(K为不同值的数量),再使用树状数组。

二、Mo算法的优化(解决原有瓶颈)

若必须使用Mo算法,可通过调整块大小、排序策略和维护方式解决超时问题。

核心优化点

  1. 块大小选择:使用sqrt(N logN)作为块大小(约400左右,针对1e5),比单纯的sqrt(N)更优。
  2. 排序策略:采用奇偶排序——块号为偶数时按R升序,奇数时按R降序,减少指针移动的总次数。
  3. 高效维护区间信息:放弃树状数组,改用值范围分块维护元素和:
    • 将A[i]的范围(1~1e5)分成若干块(如每块300个值)。
    • 维护block_sum(每个块的元素总和)和val_sum(单个值的元素总和)。
    • 添加/删除元素时,更新对应val_sum和block_sum,时间复杂度O(1)。
    • 查询≤A[R]的和时,遍历前几个完整块累加block_sum,再遍历剩余单个值累加val_sum,时间复杂度O(sqrt(M))。

复杂度分析

  • 时间:O((N+Q)sqrt(N) + Qsqrt(M)),对于1e5规模,操作数约为6e7,优化后可通过时间限制。

三、线段树(在线查询方案)

适合需要在线处理查询的场景,无需提前收集所有查询。

核心思路

线段树的每个节点维护对应区间内元素的有序列表和前缀和数组:

  • 构建时,叶子节点存储单个元素,内部节点通过归并左右子节点的有序列表得到自身的有序列表,并计算前缀和。
  • 查询时,将0~L拆分为线段树的若干节点,对每个节点的有序列表二分查找第一个大于A[R]的位置,用该节点的总元素和减去前缀和得到该节点内符合条件的元素和,最后累加所有节点的结果。

具体步骤

  1. 构建线段树:
    • 每个节点存储sorted_nums(有序元素列表)和prefix_sums(对应前缀和数组)。
    • 内部节点的sorted_nums是左右子节点sorted_nums的归并结果,prefix_sums是sorted_nums的前缀累加。
  2. 查询处理:
    • 递归拆分0~L为线段树的节点区间。
    • 对每个节点,用二分查找找到sorted_nums中第一个大于A[R]的索引pos。
    • 该节点的贡献为节点总元素和 - (pos>0 ? prefix_sums[pos-1] : 0)。
    • 累加所有节点的贡献得到最终答案。

复杂度分析

  • 构建:O(N logN),归并操作的总时间为O(N logN)。
  • 查询:O(logN * logK),其中K为节点区间的元素个数,每次查询约200次操作,1e5次查询完全可行。
  • 空间:O(N logN),存储所有节点的有序列表,约1.7e6空间,可接受。

测试用例验证

以N=4,A=[6,7,2,5]为例:

  • 查询(2,2):L=2,A[R]=2。0~2的元素为6、7、2,总总和15,≤2的和为2,15-2=13,符合输出。
  • 查询(3,1):L=3,A[R]=7。0~3的元素中无大于7的值,结果为0,符合输出。

内容的提问来源于stack exchange,提问作者ANURAG RANJAN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 18:17:06