1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct Interval<T> {
22 pub lo: i64,
24 pub hi: i64,
26 pub value: T,
28}
29
30impl<T> Interval<T> {
31 pub fn new(lo: i64, hi: i64, value: T) -> Self {
33 debug_assert!(lo <= hi, "interval must satisfy lo <= hi");
34 Self { lo, hi, value }
35 }
36
37 fn mid(&self) -> i64 {
39 (self.lo + self.hi) / 2
40 }
41
42 fn overlaps(&self, qlo: i64, qhi: i64) -> bool {
44 self.lo < qhi && qlo < self.hi
45 }
46
47 fn contains_point(&self, p: i64) -> bool {
48 self.lo <= p && p <= self.hi
49 }
50}
51
52#[derive(Debug)]
54pub struct IntervalTree<T> {
55 root: Option<Node<T>>,
56}
57
58#[derive(Debug)]
60struct Node<T> {
61 mid: i64,
62 middle: Vec<Interval<T>>,
63 left: Option<Box<Node<T>>>,
64 right: Option<Box<Node<T>>>,
65}
66
67impl<T: Clone> IntervalTree<T> {
68 pub fn new(intervals: &[Interval<T>]) -> Self {
74 Self { root: build(intervals, 0, intervals.len()) }
75 }
76
77 pub fn query(&self, qlo: i64, qhi: i64) -> Vec<Interval<T>> {
79 let mut out = Vec::new();
80 if let Some(root) = self.root.as_ref() {
81 query_node(root, qlo, qhi, &mut out);
82 }
83 out
84 }
85}
86
87fn build<T: Clone>(intervals: &[Interval<T>], lo: usize, hi: usize) -> Option<Node<T>> {
88 if lo >= hi {
89 return None;
90 }
91 let mid_idx = (lo + hi) / 2;
93 let mid_point = intervals[mid_idx].mid();
94
95 let mut middle = Vec::new();
96 let mut left_intervals = Vec::new();
97 let mut right_intervals = Vec::new();
98 for it in &intervals[lo..hi] {
99 if it.contains_point(mid_point) {
100 middle.push(it.clone());
101 } else if it.hi < mid_point {
102 left_intervals.push(it.clone());
103 } else if it.lo > mid_point {
104 right_intervals.push(it.clone());
105 } else {
106 if it.mid() < mid_point {
109 left_intervals.push(it.clone());
110 } else {
111 right_intervals.push(it.clone());
112 }
113 }
114 }
115
116 Some(Node {
117 mid: mid_point,
118 middle,
119 left: build(&left_intervals, 0, left_intervals.len()).map(Box::new),
120 right: build(&right_intervals, 0, right_intervals.len()).map(Box::new),
121 })
122}
123
124fn query_node<T: Clone>(node: &Node<T>, qlo: i64, qhi: i64, out: &mut Vec<Interval<T>>) {
125 for it in &node.middle {
127 if it.overlaps(qlo, qhi) {
128 out.push(it.clone());
129 }
130 }
131 if qlo < node.mid {
132 if let Some(left) = node.left.as_deref() {
133 query_node(left, qlo, qhi, out);
134 }
135 }
136 if qhi > node.mid {
137 if let Some(right) = node.right.as_deref() {
138 query_node(right, qlo, qhi, out);
139 }
140 }
141}