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

如何以快于O(N²)的时间统计三维点集各点的支配点数量?

三维偏序计数问题(时间复杂度O(N log²N)解法)

问题分析

你需要解决的是三维偏序计数问题:对每个点$(x_j,y_j,z_j)$,统计满足$x_k \leq x_j$、$y_k \leq y_j$、$z_k \leq z_j$的点的数量(包括点本身)。O(N²)的暴力枚举效率太低,我们可以通过降维+数据结构的方式将时间复杂度优化到O(N log²N)。

核心思路

三维偏序问题可以通过排序降维,将其转化为二维动态查询问题:

  1. 先按$x$坐标排序,这样处理每个点时,所有$x_k \leq x_j$的点要么已经处理过,要么和当前点$x$值相同(后续统一处理)。
  2. 对排序后的点,我们只需要维护一个数据结构,支持插入$(y,z)$点和查询有多少个已插入点满足$y \leq y_j$且$z \leq z_j$。

具体实现步骤

1. 点排序

将所有点按以下规则排序:

  • 优先按$x$升序排列;
  • 若$x$相同,按$y$升序排列;
  • 若$y$也相同,按$z$升序排列。

这样排序后,对于任意点$j$,所有$x_k < x_j$的点都在$j$之前,$x_k = x_j$的点要么在$j$之前,要么和$j$同组。

2. 坐标离散化

由于$y$和$z$的取值范围可能很大(比如远大于N),直接用原始值作为数据结构的下标会浪费空间且效率低,因此需要对$y$和$z$进行离散化:

  • 收集所有点的$y$值,排序后去重,得到每个$y$对应的离散化排名(rank);
  • 对$z$值执行同样的操作,得到$z$的离散化排名。

离散化后,$y$和$z$的取值范围被压缩到$[1, M]$和$[1, K]$($M,K \leq N$),适合树状数组等结构处理。

3. 二维树状数组(Fenwick Tree)处理二维查询

我们使用二维树状数组来维护已插入的点,它支持两种操作:

  • 插入操作:在位置$(y_{rank}, z_{rank})$处计数+1;
  • 查询操作:查询矩形区域$[1, y_j^{rank}] \times [1, z_j^{rank}]$内的总计数,这个值就是满足$y_k \leq y_j$且$z_k \leq z_j$的点的数量。

注意:对于$x$值相同的点,我们需要先统一查询所有同$x$点的结果,再将这些点插入到树状数组中。这是因为同$x$的点之间,只有满足$y_k \leq y_j$且$z_k \leq z_j$的点才应该被计入$j$的结果,如果先插入再查询,会导致同$x$但$y,z$更大的点被错误计入。

时间复杂度分析

  • 排序的时间复杂度是$O(N \log N)$;
  • 离散化的时间复杂度是$O(N \log N)$;
  • 每个点的插入和查询操作都是$O(\log M \log K)$,由于$M,K \leq N$,所以这部分总时间是$O(N \log^2 N)$。

整体时间复杂度为$O(N \log^2 N)$,远优于$O(N^2)$的暴力解法。

替代方案:CDQ分治

如果觉得二维树状数组实现起来比较繁琐,也可以用CDQ分治来解决这个问题,时间复杂度同样是$O(N \log^2 N)$。其核心思路是通过分治将三维偏序拆解为多个二维偏序问题,再用一维树状数组处理二维查询,常数可能比二维树状数组更小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:45:34