A 3log Method for Finding Depths

Revision en1, by _paper_, 2026-05-15 17:01:59

Here is a method to find the depth of every node in

Unable to parse markup [type=CF_MATHJAX]

$ operations.

Root the tree at

Unable to parse markup [type=CF_MATHJAX]

$, and let

Unable to parse markup [type=CF_MATHJAX]

$.

Take a power of two

Unable to parse markup [type=CF_MATHJAX]

$ such that

Unable to parse markup [type=CF_MATHJAX]

$. Since the depth of any node in the tree is less than

Unable to parse markup [type=CF_MATHJAX]

$, initially we can assume that the depth of every non-root node lies in

Unable to parse markup [type=CF_MATHJAX]

$.

Then we keep binary-splitting this interval.

Suppose that currently every node belongs to a depth segment of length

Unable to parse markup [type=CF_MATHJAX]

$. For a node

Unable to parse markup [type=CF_MATHJAX]

$, let

Unable to parse markup [type=CF_MATHJAX]

$ be the index of the segment it currently belongs to, that is:

Unable to parse markup [type=CF_MATHJAX]

$

In each binary-splitting round, we want to determine whether each node is in the left half or the right half of its current segment.

Consider processing all segments in parallel by grouping their indices modulo

Unable to parse markup [type=CF_MATHJAX]

$.

For

Unable to parse markup [type=CF_MATHJAX]

$, we make one query:

  • if

Unable to parse markup [type=CF_MATHJAX]

$, set

Unable to parse markup [type=CF_MATHJAX]

$; - otherwise, set

Unable to parse markup [type=CF_MATHJAX]

$.

This query can split all nodes satisfying

Unable to parse markup [type=CF_MATHJAX]

$.

Consider a node

Unable to parse markup [type=CF_MATHJAX]

$ whose side we want to determine, and suppose the index of its segment is

Unable to parse markup [type=CF_MATHJAX]

$. The only nodes that can actually affect it are those in the previous segment

Unable to parse markup [type=CF_MATHJAX]

$.

All other selected segments are at least two full depth segments away from the segment of

Unable to parse markup [type=CF_MATHJAX]

$, so their distance to

Unable to parse markup [type=CF_MATHJAX]

$ must be greater than

Unable to parse markup [type=CF_MATHJAX]

$, and they will not light up

Unable to parse markup [type=CF_MATHJAX]

$.

Therefore:

  • if

Unable to parse markup [type=CF_MATHJAX]

$ is in the left half of its current segment, then after moving

Unable to parse markup [type=CF_MATHJAX]

$ steps towards the root, it reaches the previous segment, so it will be lit up; - if

Unable to parse markup [type=CF_MATHJAX]

$ is in the right half of its current segment, then its distance to every node in the previous segment is greater than

Unable to parse markup [type=CF_MATHJAX]

$, so it will not be lit up.

Thus, from the query result, we can directly determine which half

Unable to parse markup [type=CF_MATHJAX]

$ should enter.

There is also the case

Unable to parse markup [type=CF_MATHJAX]

$: the first segment has no previous segment, so we additionally need to set

Unable to parse markup [type=CF_MATHJAX]

$ for the root.

Each round only needs

Unable to parse markup [type=CF_MATHJAX]

$ queries, and there are

Unable to parse markup [type=CF_MATHJAX]

$ rounds. Therefore, the number of queries needed to find all depths is at most:

Unable to parse markup [type=CF_MATHJAX]

$.

In fact, with some small optimizations, the number of queries can be reduced by a few more. Also, this method is more consistent with the official editorial's method for finding the parent of each node.

Translated with the assistance of ChatGPT.

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en4 English _paper_ 2026-05-15 17:06:07 12
en3 English _paper_ 2026-05-15 17:05:01 34
en2 English _paper_ 2026-05-15 17:03:20 180
en1 English _paper_ 2026-05-15 17:01:59 2474 Initial revision (published)