E - Laser Takahashi 解説
by
spheniscine
Pseudoangle
Define the pseudoangle / pseudo-argument of a 2D vector \(\psi(x, y)\) as:
\[ \text{sgn}^ +\, y := \begin{cases} \text{if }y \ge 0: &1 \\ \text{else}: &-1 \end{cases} \\[0.5em] \psi(x, y) := (\text{sgn}^ +\, y) \left( 1 - \frac{x}{|x| + |y|} \right) \]
The advantage of using this function is that 1: for vectors with integer or rational coordinates, the pseudoangle is rational, and 2: sorting by the pseudoangle (using comparison of rational numbers with sufficiently large integer types) should produce the same effect of sorting by a theoretically perfect \(\text{atan2}\) without precision issues, and is generally faster than the actual atan2 function.
Explanation of this function: \({\large\frac{x}{|x| + |y|}} \in [-1, 1]\) projects the vector onto the “unit diamond” (the Manhattan-distance equivalent of the unit circle) and takes its \(x\)-coordinate, which is then mapped onto the range \(\psi(x, y) \in (-2, 2]\) depending on the half plane determined by the (positive-biased) signum of \(y\).
There are several variants of the pseudoangle function, but this variant preserves both the “starting point” and sign of typical \(\text{atan2}\) implementations, and thus can be used to solve this test problem (though note that there you must define the special case \(\psi(0, 0) = \text{atan2}(0, 0) = 0\))
Source: https://vegard.wiki/w/Pseudoangles
An advantage this method has over the polar sorting method in the official editorial (half-plane + cross-product): as the pseudoangle is a specific value, they can be precalculated and stored, e.g. for this problem you can convert all the vectors into pseudoangles and work only with them. It also means that for some other more complex problems, you may reduce the fractions to the lowest terms, and then hash them for equality comparisons (e.g. for a hashmap, or Zobrist hashing).
A disadvantage is that comparison of pseudoangles as rationals could produce integers with magnitude up to \(6 L^2\), where \(L\) is the maximum magnitude of possible coordinates, as opposed to \(2L^2\) by the cross-product method (which is also easily reducible to \(L^2\)). Thus it is more likely to cause overflows (but fortunately doesn’t for \(L = 10^9\) using signed 64-bit integers).
投稿日時:
最終更新:
