#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Debug)]
pub struct SegTreeNode(pub usize);
impl SegTreeNode {
#[inline]
pub fn left_child(&self) -> SegTreeNode {
SegTreeNode(self.0 * 2)
}
#[inline]
pub fn right_child(&self) -> SegTreeNode {
SegTreeNode(self.0 * 2 + 1)
}
#[inline]
pub fn parent(&self) -> SegTreeNode {
if self.is_root() {
panic!("Root node has no parent")
} else {
SegTreeNode(self.0 / 2)
}
}
#[inline]
pub fn sibling(&self) -> SegTreeNode {
SegTreeNode(self.0 ^ 1)
}
#[inline]
pub fn sibling_safe(&self) -> SegTreeNode {
if self.is_root() {
panic!("Root node has no sibling")
}
SegTreeNode(self.0 ^ 1)
}
#[inline]
pub fn is_root(&self) -> bool {
self.0 == 1
}
#[inline]
pub fn is_left_child(&self) -> bool {
!self.is_root() && self.0 & 1 == 0
}
#[inline]
pub fn is_left_child_if_not_root(&self) -> bool {
self.0 & 1 == 0
}
#[inline]
pub fn is_right_child(&self) -> bool {
!self.is_root() && self.0 & 1 == 1
}
#[inline]
pub fn is_right_child_if_not_root(&self) -> bool {
self.0 & 1 == 1
}
#[inline]
pub fn depth(&self) -> u32 {
self.0.ilog2()
}
#[inline]
pub fn is_leaf(&self, max_depth: u32) -> bool {
self.depth() == max_depth
}
#[inline]
pub fn size(&self, max_depth: u32) -> usize {
1 << (max_depth - self.depth())
}
#[inline]
pub fn left_bound(&self, max_depth: u32) -> usize {
let depth = self.depth();
let pos = self.0 - (1 << depth);
pos * (1 << (max_depth - depth))
}
#[inline]
pub fn right_bound(&self, max_depth: u32) -> usize {
let depth = self.depth();
let pos = self.0 - (1 << depth);
(pos + 1) * (1 << (max_depth - depth))
}
#[inline]
pub fn mid(&self, max_depth: u32) -> usize {
let depth = self.depth();
let pos = self.0 - (1 << depth);
let range = 1 << (max_depth - depth);
pos * range + range / 2
}
#[inline]
pub fn node_bounds(&self, max_depth: u32) -> (usize, usize) {
let depth = self.depth();
let pos = self.0 - (1 << depth);
let range = 1 << (max_depth - depth);
(pos * range, (pos + 1) * range)
}
pub fn get_lca_from_same_depth(left: SegTreeNode, right: SegTreeNode) -> SegTreeNode {
let xor = left.0 ^ right.0;
if xor == 0 {
return left;
}
let highest = usize::BITS - 1 - xor.leading_zeros();
let shift = (highest + 1) as usize;
SegTreeNode(left.0 >> shift)
}
pub fn get_lca_from_different_depth(
mut left: SegTreeNode,
mut right: SegTreeNode,
) -> SegTreeNode {
if left.depth() >= right.depth() {
left.0 >>= left.depth() - right.depth();
} else {
right.0 >>= right.depth() - left.depth();
}
Self::get_lca_from_same_depth(left, right)
}
pub fn get_left_binding_node(&self) -> SegTreeNode {
SegTreeNode((self.0 >> self.0.trailing_zeros()).max(1))
}
pub fn get_right_binding_node(&self) -> SegTreeNode {
SegTreeNode((self.0 >> self.0.trailing_ones()).max(1))
}
}
#[cfg(test)]
mod tests {
use super::SegTreeNode;
#[test]
fn test_basic_navigation() {
let root = SegTreeNode(1);
let left = root.left_child();
let right = root.right_child();
assert_eq!(left.0, 2);
assert_eq!(right.0, 3);
assert_eq!(left.parent().0, 1);
assert_eq!(right.parent().0, 1);
}
#[test]
#[should_panic(expected = "Root node has no sibling")]
fn test_root_node() {
let root = SegTreeNode(1);
assert!(root.is_root());
assert!(!root.is_left_child());
assert!(!root.is_right_child());
root.sibling_safe();
}
#[test]
fn test_sibling_and_child_properties() {
let node2 = SegTreeNode(2);
let node3 = SegTreeNode(3);
assert_eq!(node2.sibling().0, 3);
assert_eq!(node3.sibling().0, 2);
assert!(node2.is_left_child());
assert!(node3.is_right_child());
}
#[test]
fn test_depth_calculation() {
let root = SegTreeNode(1);
let depth1 = SegTreeNode(2);
let depth2 = SegTreeNode(4);
assert_eq!(root.depth(), 0);
assert_eq!(depth1.depth(), 1);
assert_eq!(depth2.depth(), 2);
}
#[test]
fn test_bounds_calculation() {
let root = SegTreeNode(1);
let max_depth = 3;
assert_eq!(root.size(max_depth), 8);
assert_eq!(root.left_bound(max_depth), 0);
assert_eq!(root.right_bound(max_depth), 8);
assert_eq!(root.node_bounds(max_depth), (0, 8));
}
#[test]
fn test_leaf_detection() {
let root = SegTreeNode(1);
let leaf = SegTreeNode(8);
let max_depth = 3;
assert!(!root.is_leaf(max_depth));
assert!(leaf.is_leaf(max_depth));
}
#[test]
fn test_lca_same_depth() {
let node4 = SegTreeNode(4);
let node5 = SegTreeNode(5);
let lca = SegTreeNode::get_lca_from_same_depth(node4, node5);
assert_eq!(lca.0, 2);
}
#[test]
fn test_lca_different_depth() {
let node2 = SegTreeNode(2);
let node4 = SegTreeNode(4);
let lca = SegTreeNode::get_lca_from_different_depth(node2, node4);
assert_eq!(lca.0, 2);
}
#[test]
fn test_binding_nodes() {
let node4 = SegTreeNode(4);
let node5 = SegTreeNode(5);
let left_binding = node4.get_left_binding_node();
let right_binding = node5.get_right_binding_node();
assert!(left_binding.0 > 0);
assert!(right_binding.0 > 0);
}
}