Hi Codeforces! Here I want to share a method to count dominating pairs in high dimension, while the number of point($$$n$$$) is small but dimensionality($$$k$$$) is large (like $$$n = 32768, k = 8$$$).
The problem of counting dominating pairs in K-Dimension is as follows:
For two $$$k$$$-tuples $$$a = (a_0, a_1, \dots, a_{k - 1})$$$ and $$$b = (b_0, b_1, \dots, b_{k - 1})$$$, define $$$dom(a, b) = \prod\limits_{i = 0}^{k - 1}[a_i \geq b_i]$$$, which outputs $$$1$$$ if each $$$a_i$$$ is greater than or equal to $$$b_i$$$ ($$$a$$$ dominates $$$b$$$), otherwise $$$0$$$.
Given $$$n$$$ $$$k$$$-tuples $$$t_0, t_1, \dots, t_{n - 1}$$$, for each $$$i \in [0, n)$$$, compute $$$g(i) = \sum\limits_{j = 0}^{n - 1} dom(t_i, t_j)$$$.
When $$$k = 2$$$, the problem simplifies to counting inversions, solvable directly using a Fenwick Tree.
For $$$k = 3$$$, one can consider Divide and Conquer (D&C) approach, achieving a complexity of $$$O(n \log^2 n)$$$, which is excellent. Alternatively, a K-D Tree approach achieves $$$O(n \sqrt{n})$$$ complexity, also a good option.
For $$$k = 4$$$, D&C embedded with D&C or just K-D Tree solutions are less optimal, with reduced complexity benefits.
At $$$k = 5$$$, the Divide and conquer approach is notably less efficient than brute force, and the K-D Tree offers no significant advantage over brute force.
An optimized brute force approach involves using bitsets to enhance efficiency.
Brute Force Approach
An obvious brute force approach is to enumerate $$$i, j$$$ and check whether $$$p_i$$$ dominates $$$p_j$$$ by each dimension in $$$O(k)$$$ time. The overall complexity is $$$O(n^2 k)$$$.
A key property is that $$$dom[(a_{0..i}), (b_{0..i})] = 1$$$ implies $$$dom[(a_{0..i + 1}), (b_{0..i + 1})] = 1$$$. Therefore, the enumeration order can be swapped. First, enumerating dimensions (tuple indices) $$$d$$$, maintaining the dominant relation up to dimension $$$d$$$, and computing the relation up to next dimension based on the current order:
Let $$$b_{d, i, j} = f(p_{i, 0..d - 1}, p_{j, 0..d - 1})$$$. Then:
In practice, dimension $$$d$$$ can be omitted because each $$$(i, j)$$$ pair is independent, simplifying to:
Total complexity is $$$O(n^2 k)$$$.
Bitset Optimization
It's observed that this problem can be optimized using bitset. Utilize a 2D array bitset<N> b[N]
. Considering the transition $$$[p_{i, d} \geq p_{j, d}]$$$, sort points by $$$p_{i, d}$$$ to obtain $$$q$$$, where $$$q_i$$$ is located at $$$p$$$ index $$$l_i$$$.
Enumerating from $$$0$$$ to $$$n - 1$$$, deduce a relationship array $$$r$$$, where $$$r_j$$$ indicates $$$p_{l_j, d} \leq q_{i, d}$$$. Then update $$$b_{l_i}$$$ using $$$b_{l_i} \gets \left(b_{l_i} \text{ bitand } r\right)$$$.
Time complexity is $$$O(\frac{n^2 k}{w})$$$, space complexity is $$$O(\frac{n^2}{z})$$$, where $$$w = 64, z = 8$$$, with excellent constant factors.
Space Optimization
If space constraints are strict, use a grouping method: process $$$S (S \geq w)$$$ points $$$p_{l..l + S - 1}$$$ together. Complexity includes sorting $$$O(nk \log n)$$$, deriving $$$r$$$ for each group $$$O(nk)$$$, and updating $$$b$$$ for each group $$$O(\frac{Snk}{w})$$$, achieving $$$O(\frac{n^2 k}{w})$$$ time and $$$O(\frac{Sk}{z})$$$ space complexity, where $$$S \geq w$$$.
Divide $$$S$$$ (where $$$S \geq w$$$) points $$$p_{l..l + S - 1}$$$ into groups, and each time focus only on the values of $$$b_{l} \dots b_{l + S - 1}$$$. Analyzing the complexity:
- Sorting takes $$$O(nk\log n)$$$ time;
- Calculating $$$r$$$ for each group is $$$O(nk)$$$, thus the total complexity is $$$O(\frac{n^2k}{S})$$$. Thus, without space optimization, calculating $$$r$$$ has a complexity of $$$O(nk)$$$;
- Calculating the array $$$b$$$ for each group takes $$$O(\frac{Snk}{w})$$$, resulting in a total complexity of $$$O(\frac{n^2k}{w})$$$.
Since $$$S \geq w$$$, the time complexity is $$$O(\frac{n^2k}{w})$$$, and the space complexity is $$$O(\frac{Sn}{z})$$$.
Related problem: CF1826E.
There is also a zh-cn version of this post. If you have any interest, try this link.