pub struct LiChaoTree<X, L> {
range: Range<X>,
nodes: Vec<LiChaoNode<X, L>>,
}Fields§
§range: Range<X>§nodes: Vec<LiChaoNode<X, L>>Implementations§
Source§impl<X, L> LiChaoTree<X, L>where
X: IntBase,
L: LiChaoLine<X>,
impl<X, L> LiChaoTree<X, L>where
X: IntBase,
L: LiChaoLine<X>,
pub fn new(range: Range<X>) -> Self
Sourcefn push_node(&mut self, segment: LiChaoSegment<X, L>) -> u32
fn push_node(&mut self, segment: LiChaoSegment<X, L>) -> u32
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 207)
165 fn add_segment_at(
166 &mut self,
167 mut index: u32,
168 mut segment: LiChaoSegment<X, L>,
169 mut left: X,
170 mut right: X,
171 ) {
172 loop {
173 let last = right - X::one();
174 let middle = if left == last {
175 left
176 } else {
177 left.midpoint(last).min(last - X::one())
178 };
179 let split = middle + X::one();
180 if self.nodes[index as usize].segment.covers(left, right) && segment.covers(left, right)
181 {
182 let candidate_left = segment.line.evaluate(left);
183 let candidate_right = segment.line.evaluate(last);
184 let child = match place_line(
185 &mut self.nodes[index as usize].segment.line,
186 &mut segment.line,
187 left,
188 middle,
189 last,
190 candidate_left,
191 candidate_right,
192 ) {
193 None => return,
194 Some((Branch::Left, _, _)) => {
195 right = split;
196 segment.range.end = right;
197 0
198 }
199 Some((Branch::Right, _, _)) => {
200 left = split;
201 segment.range.start = left;
202 1
203 }
204 };
205 let next = self.nodes[index as usize].children[child];
206 if next == !0 {
207 let next = self.push_node(segment);
208 self.nodes[index as usize].children[child] = next;
209 return;
210 }
211 index = next;
212 continue;
213 }
214 let segment_right = segment.range.end - X::one();
215 if self.nodes[index as usize]
216 .segment
217 .evaluate(segment.range.start)
218 <= segment.line.evaluate(segment.range.start)
219 && self.nodes[index as usize].segment.evaluate(segment_right)
220 <= segment.line.evaluate(segment_right)
221 {
222 return;
223 }
224 let current = &self.nodes[index as usize].segment;
225 let current_left = current.range.start;
226 let current_right = current.range.end - X::one();
227 if current.line.evaluate(current_left) >= segment.evaluate(current_left)
228 && current.line.evaluate(current_right) >= segment.evaluate(current_right)
229 {
230 self.nodes[index as usize].segment = segment;
231 return;
232 }
233 if segment.covers(left, right) {
234 swap(&mut self.nodes[index as usize].segment, &mut segment);
235 }
236 let child;
237 if segment.range.end <= split {
238 child = 0;
239 right = split;
240 } else if middle < segment.range.start {
241 child = 1;
242 left = split;
243 } else {
244 let right_segment = LiChaoSegment {
245 range: split..segment.range.end,
246 line: segment.line,
247 };
248 segment.range.end = split;
249 let next = self.nodes[index as usize].children[0];
250 if next == !0 {
251 let next = self.push_node(segment);
252 self.nodes[index as usize].children[0] = next;
253 } else {
254 self.add_segment_at(next, segment, left, split);
255 }
256 let next = self.nodes[index as usize].children[1];
257 if next == !0 {
258 let next = self.push_node(right_segment);
259 self.nodes[index as usize].children[1] = next;
260 } else {
261 self.add_segment_at(next, right_segment, split, right);
262 }
263 return;
264 }
265 let next = self.nodes[index as usize].children[child];
266 if next == !0 {
267 let next = self.push_node(segment);
268 self.nodes[index as usize].children[child] = next;
269 return;
270 }
271 index = next;
272 }
273 }pub fn add_line(&mut self, line: L)
pub fn add_segment(&mut self, range: Range<X>, line: L)
Sourcefn add_segment_at(
&mut self,
index: u32,
segment: LiChaoSegment<X, L>,
left: X,
right: X,
)
fn add_segment_at( &mut self, index: u32, segment: LiChaoSegment<X, L>, left: X, right: X, )
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (lines 142-150)
141 pub fn add_line(&mut self, line: L) {
142 self.add_segment_at(
143 0,
144 LiChaoSegment {
145 range: self.range.clone(),
146 line,
147 },
148 self.range.start,
149 self.range.end,
150 );
151 }
152
153 pub fn add_segment(&mut self, range: Range<X>, line: L) {
154 assert!(self.range.start <= range.start && range.end <= self.range.end);
155 if range.start < range.end {
156 self.add_segment_at(
157 0,
158 LiChaoSegment { range, line },
159 self.range.start,
160 self.range.end,
161 );
162 }
163 }
164
165 fn add_segment_at(
166 &mut self,
167 mut index: u32,
168 mut segment: LiChaoSegment<X, L>,
169 mut left: X,
170 mut right: X,
171 ) {
172 loop {
173 let last = right - X::one();
174 let middle = if left == last {
175 left
176 } else {
177 left.midpoint(last).min(last - X::one())
178 };
179 let split = middle + X::one();
180 if self.nodes[index as usize].segment.covers(left, right) && segment.covers(left, right)
181 {
182 let candidate_left = segment.line.evaluate(left);
183 let candidate_right = segment.line.evaluate(last);
184 let child = match place_line(
185 &mut self.nodes[index as usize].segment.line,
186 &mut segment.line,
187 left,
188 middle,
189 last,
190 candidate_left,
191 candidate_right,
192 ) {
193 None => return,
194 Some((Branch::Left, _, _)) => {
195 right = split;
196 segment.range.end = right;
197 0
198 }
199 Some((Branch::Right, _, _)) => {
200 left = split;
201 segment.range.start = left;
202 1
203 }
204 };
205 let next = self.nodes[index as usize].children[child];
206 if next == !0 {
207 let next = self.push_node(segment);
208 self.nodes[index as usize].children[child] = next;
209 return;
210 }
211 index = next;
212 continue;
213 }
214 let segment_right = segment.range.end - X::one();
215 if self.nodes[index as usize]
216 .segment
217 .evaluate(segment.range.start)
218 <= segment.line.evaluate(segment.range.start)
219 && self.nodes[index as usize].segment.evaluate(segment_right)
220 <= segment.line.evaluate(segment_right)
221 {
222 return;
223 }
224 let current = &self.nodes[index as usize].segment;
225 let current_left = current.range.start;
226 let current_right = current.range.end - X::one();
227 if current.line.evaluate(current_left) >= segment.evaluate(current_left)
228 && current.line.evaluate(current_right) >= segment.evaluate(current_right)
229 {
230 self.nodes[index as usize].segment = segment;
231 return;
232 }
233 if segment.covers(left, right) {
234 swap(&mut self.nodes[index as usize].segment, &mut segment);
235 }
236 let child;
237 if segment.range.end <= split {
238 child = 0;
239 right = split;
240 } else if middle < segment.range.start {
241 child = 1;
242 left = split;
243 } else {
244 let right_segment = LiChaoSegment {
245 range: split..segment.range.end,
246 line: segment.line,
247 };
248 segment.range.end = split;
249 let next = self.nodes[index as usize].children[0];
250 if next == !0 {
251 let next = self.push_node(segment);
252 self.nodes[index as usize].children[0] = next;
253 } else {
254 self.add_segment_at(next, segment, left, split);
255 }
256 let next = self.nodes[index as usize].children[1];
257 if next == !0 {
258 let next = self.push_node(right_segment);
259 self.nodes[index as usize].children[1] = next;
260 } else {
261 self.add_segment_at(next, right_segment, split, right);
262 }
263 return;
264 }
265 let next = self.nodes[index as usize].children[child];
266 if next == !0 {
267 let next = self.push_node(segment);
268 self.nodes[index as usize].children[child] = next;
269 return;
270 }
271 index = next;
272 }
273 }pub fn query_min(&self, x: X) -> Option<L::Output>
Trait Implementations§
Auto Trait Implementations§
impl<X, L> Freeze for LiChaoTree<X, L>
impl<X, L> RefUnwindSafe for LiChaoTree<X, L>
impl<X, L> Send for LiChaoTree<X, L>
impl<X, L> Sync for LiChaoTree<X, L>
impl<X, L> Unpin for LiChaoTree<X, L>
impl<X, L> UnsafeUnpin for LiChaoTree<X, L>
impl<X, L> UnwindSafe for LiChaoTree<X, L>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more