Content: Data structs
Date:2025.7.19

内容

  • 三维偏序问题
  • CDQ分治
  • 整体二分
  • 分块
  • 莫队算法

具体内容

三维偏序问题

问题描述

给定一些三元组 (ai,bi,ci)(a_i, b_i, c_i),询问对于三元组 (aj,bj,cj)(a_j, b_j, c_j),有多少个三元组满足 aiaja_i \le a_jbibjb_i \le b_jcicjc_i \le c_j

首先对于这个问题,我们考虑先去重,然后排序。排序规则如下:

  • 如果 aiaja_i \ne a_j,则返回 ai<aja_i < a_j
  • 如果 bibjb_i \ne b_j,则返回 bi<bjb_i < b_j
  • 否则返回 ci<cjc_i < c_j

这样我们就把 ai<aja_i < a_j 的条件去掉了。

接下来我们考虑分治,定义函数 solve(l,r)solve(l, r) 表示当前解决到了区间 [l,r][l, r],取其中点 midmid,将原序列的问题转化为三个部分:

  • j<imidj < i \le mid,由 solve(l,mid)solve(l, mid) 解决。
  • mid<j<imid < j < i,由 solve(mid+1,r)solve(mid + 1, r) 解决。
  • jmid<ij \le mid < i,即被 midmid 分成了两个部分。

对于第三种情况,我们需要解决的是如下问题:

问题描述

在区间 [l,r][l,r] 中,有多少对二元组 (i,j)(i, j) (其中 iji \ne j)满足 bi<bjb_i < b_jci<cjc_i < c_j

可见问题转化为了二维偏序问题,用线段树解决就可以。

整体二分

普通的二分操作是直接对于每个询问二分答案,判断答案是否合法。
整体二分的思路是将所有询问一起二分,根据二分的答案对询问进行分类,再逐步求解。

例题: