struct IndexedLiChaoTree<'a, X, L>where
L: LiChaoLine<X>,{
size: usize,
coordinates: &'a [X],
lines: Vec<L>,
}Fields§
§size: usize§coordinates: &'a [X]§lines: Vec<L>Implementations§
Source§impl<X, L> IndexedLiChaoTree<'_, X, L>where
X: Copy,
L: LiChaoLine<X>,
impl<X, L> IndexedLiChaoTree<'_, X, L>where
X: Copy,
L: LiChaoLine<X>,
Sourcefn new(coordinates: &[X]) -> IndexedLiChaoTree<'_, X, L>
fn new(coordinates: &[X]) -> IndexedLiChaoTree<'_, X, L>
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 396)
349 pub fn execute(self) -> Vec<Option<L::Output>> {
350 let mut markers = Vec::with_capacity(2 * self.events.len());
351 for (i, event) in self.events.iter().enumerate() {
352 let i = i as u32;
353 match *event {
354 LiChaoEvent::Line(_) => {}
355 LiChaoEvent::Segment(left, right, _) => {
356 markers.push((left, i << 2));
357 markers.push((right, i << 2 | 1));
358 }
359 LiChaoEvent::Query(x, _) => markers.push((x, i << 2 | 2)),
360 }
361 }
362 markers.radix_sort_by_key(|&(x, _)| x);
363
364 let mut positions = vec![[0u32; 2]; self.events.len()];
365 let mut coordinates = Vec::with_capacity(self.queries);
366 let mut left = 0;
367 while left < markers.len() {
368 let x = markers[left].0;
369 let mut right = left + 1;
370 while right < markers.len() && markers[right].0 == x {
371 right += 1;
372 }
373 let index = coordinates.len() as u32;
374 let mut queried = false;
375 for &(_, marker) in &markers[left..right] {
376 let event = (marker >> 2) as usize;
377 match marker & 3 {
378 0 => positions[event][0] = index,
379 1 => positions[event][1] = index,
380 _ => {
381 positions[event][0] = index;
382 queried = true;
383 }
384 }
385 }
386 if queried {
387 coordinates.push(x);
388 }
389 left = right;
390 }
391 if let Some(&x) = coordinates.last() {
392 coordinates.resize(coordinates.len().next_power_of_two(), x);
393 coordinates.push(x);
394 }
395
396 let mut tree = IndexedLiChaoTree::new(&coordinates);
397 let mut result = vec![None; self.queries];
398 for (i, event) in self.events.into_iter().enumerate() {
399 match event {
400 LiChaoEvent::Line(line) => tree.add_line(line),
401 LiChaoEvent::Segment(_, _, line) => {
402 let [left, right] = positions[i];
403 tree.add_segment(left as usize..right as usize, line);
404 }
405 LiChaoEvent::Query(_, output) => {
406 result[output as usize] = tree.query_min(positions[i][0] as usize);
407 }
408 }
409 }
410 result
411 }Sourcefn add_line(&mut self, line: L)
fn add_line(&mut self, line: L)
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 400)
349 pub fn execute(self) -> Vec<Option<L::Output>> {
350 let mut markers = Vec::with_capacity(2 * self.events.len());
351 for (i, event) in self.events.iter().enumerate() {
352 let i = i as u32;
353 match *event {
354 LiChaoEvent::Line(_) => {}
355 LiChaoEvent::Segment(left, right, _) => {
356 markers.push((left, i << 2));
357 markers.push((right, i << 2 | 1));
358 }
359 LiChaoEvent::Query(x, _) => markers.push((x, i << 2 | 2)),
360 }
361 }
362 markers.radix_sort_by_key(|&(x, _)| x);
363
364 let mut positions = vec![[0u32; 2]; self.events.len()];
365 let mut coordinates = Vec::with_capacity(self.queries);
366 let mut left = 0;
367 while left < markers.len() {
368 let x = markers[left].0;
369 let mut right = left + 1;
370 while right < markers.len() && markers[right].0 == x {
371 right += 1;
372 }
373 let index = coordinates.len() as u32;
374 let mut queried = false;
375 for &(_, marker) in &markers[left..right] {
376 let event = (marker >> 2) as usize;
377 match marker & 3 {
378 0 => positions[event][0] = index,
379 1 => positions[event][1] = index,
380 _ => {
381 positions[event][0] = index;
382 queried = true;
383 }
384 }
385 }
386 if queried {
387 coordinates.push(x);
388 }
389 left = right;
390 }
391 if let Some(&x) = coordinates.last() {
392 coordinates.resize(coordinates.len().next_power_of_two(), x);
393 coordinates.push(x);
394 }
395
396 let mut tree = IndexedLiChaoTree::new(&coordinates);
397 let mut result = vec![None; self.queries];
398 for (i, event) in self.events.into_iter().enumerate() {
399 match event {
400 LiChaoEvent::Line(line) => tree.add_line(line),
401 LiChaoEvent::Segment(_, _, line) => {
402 let [left, right] = positions[i];
403 tree.add_segment(left as usize..right as usize, line);
404 }
405 LiChaoEvent::Query(_, output) => {
406 result[output as usize] = tree.query_min(positions[i][0] as usize);
407 }
408 }
409 }
410 result
411 }Sourcefn add_line_at(&mut self, index: usize, height: usize, line: L)
fn add_line_at(&mut self, index: usize, height: usize, line: L)
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 439)
437 fn add_line(&mut self, line: L) {
438 if self.size != 0 {
439 self.add_line_at(1, self.size.trailing_zeros() as usize, line);
440 }
441 }
442
443 fn add_line_at(&mut self, mut index: usize, height: usize, mut line: L) {
444 let mut left = (index << height) - self.size;
445 let mut right = left + (1 << height);
446 let mut values = (
447 line.evaluate(self.coordinates[left]),
448 line.evaluate(self.coordinates[right]),
449 );
450 loop {
451 if left + 1 == right {
452 if values.0 < self.lines[index].evaluate(self.coordinates[left]) {
453 self.lines[index] = line;
454 }
455 return;
456 }
457 let middle = (left + right) / 2;
458 match place_line(
459 &mut self.lines[index],
460 &mut line,
461 self.coordinates[left],
462 self.coordinates[middle],
463 self.coordinates[right],
464 values.0,
465 values.1,
466 ) {
467 None => return,
468 Some((Branch::Left, left_value, right_value)) => {
469 index *= 2;
470 right = middle;
471 values = (left_value, right_value);
472 }
473 Some((Branch::Right, left_value, right_value)) => {
474 index = 2 * index + 1;
475 left = middle;
476 values = (left_value, right_value);
477 }
478 }
479 }
480 }
481
482 fn add_segment(&mut self, range: Range<usize>, line: L) {
483 let n = self.size;
484 if range.start == range.end {
485 return;
486 }
487 let mut left = n + range.start - 1;
488 let mut right = n + range.end;
489 let width = (left ^ right).ilog2();
490 let mask = (1usize << width) - 1;
491 let fixed = left;
492 left = !left & mask;
493 while left != 0 {
494 let height = left.trailing_zeros();
495 left &= left - 1;
496 self.add_line_at((fixed >> height) ^ 1, height as usize, line);
497 }
498 let fixed = right;
499 right &= mask;
500 while right != 0 {
501 let height = right.trailing_zeros();
502 right &= right - 1;
503 self.add_line_at((fixed >> height) ^ 1, height as usize, line);
504 }
505 }Sourcefn add_segment(&mut self, range: Range<usize>, line: L)
fn add_segment(&mut self, range: Range<usize>, line: L)
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 403)
349 pub fn execute(self) -> Vec<Option<L::Output>> {
350 let mut markers = Vec::with_capacity(2 * self.events.len());
351 for (i, event) in self.events.iter().enumerate() {
352 let i = i as u32;
353 match *event {
354 LiChaoEvent::Line(_) => {}
355 LiChaoEvent::Segment(left, right, _) => {
356 markers.push((left, i << 2));
357 markers.push((right, i << 2 | 1));
358 }
359 LiChaoEvent::Query(x, _) => markers.push((x, i << 2 | 2)),
360 }
361 }
362 markers.radix_sort_by_key(|&(x, _)| x);
363
364 let mut positions = vec![[0u32; 2]; self.events.len()];
365 let mut coordinates = Vec::with_capacity(self.queries);
366 let mut left = 0;
367 while left < markers.len() {
368 let x = markers[left].0;
369 let mut right = left + 1;
370 while right < markers.len() && markers[right].0 == x {
371 right += 1;
372 }
373 let index = coordinates.len() as u32;
374 let mut queried = false;
375 for &(_, marker) in &markers[left..right] {
376 let event = (marker >> 2) as usize;
377 match marker & 3 {
378 0 => positions[event][0] = index,
379 1 => positions[event][1] = index,
380 _ => {
381 positions[event][0] = index;
382 queried = true;
383 }
384 }
385 }
386 if queried {
387 coordinates.push(x);
388 }
389 left = right;
390 }
391 if let Some(&x) = coordinates.last() {
392 coordinates.resize(coordinates.len().next_power_of_two(), x);
393 coordinates.push(x);
394 }
395
396 let mut tree = IndexedLiChaoTree::new(&coordinates);
397 let mut result = vec![None; self.queries];
398 for (i, event) in self.events.into_iter().enumerate() {
399 match event {
400 LiChaoEvent::Line(line) => tree.add_line(line),
401 LiChaoEvent::Segment(_, _, line) => {
402 let [left, right] = positions[i];
403 tree.add_segment(left as usize..right as usize, line);
404 }
405 LiChaoEvent::Query(_, output) => {
406 result[output as usize] = tree.query_min(positions[i][0] as usize);
407 }
408 }
409 }
410 result
411 }Sourcefn query_min(&self, index: usize) -> Option<L::Output>
fn query_min(&self, index: usize) -> Option<L::Output>
Examples found in repository?
crates/competitive/src/data_structure/li_chao_tree.rs (line 406)
349 pub fn execute(self) -> Vec<Option<L::Output>> {
350 let mut markers = Vec::with_capacity(2 * self.events.len());
351 for (i, event) in self.events.iter().enumerate() {
352 let i = i as u32;
353 match *event {
354 LiChaoEvent::Line(_) => {}
355 LiChaoEvent::Segment(left, right, _) => {
356 markers.push((left, i << 2));
357 markers.push((right, i << 2 | 1));
358 }
359 LiChaoEvent::Query(x, _) => markers.push((x, i << 2 | 2)),
360 }
361 }
362 markers.radix_sort_by_key(|&(x, _)| x);
363
364 let mut positions = vec![[0u32; 2]; self.events.len()];
365 let mut coordinates = Vec::with_capacity(self.queries);
366 let mut left = 0;
367 while left < markers.len() {
368 let x = markers[left].0;
369 let mut right = left + 1;
370 while right < markers.len() && markers[right].0 == x {
371 right += 1;
372 }
373 let index = coordinates.len() as u32;
374 let mut queried = false;
375 for &(_, marker) in &markers[left..right] {
376 let event = (marker >> 2) as usize;
377 match marker & 3 {
378 0 => positions[event][0] = index,
379 1 => positions[event][1] = index,
380 _ => {
381 positions[event][0] = index;
382 queried = true;
383 }
384 }
385 }
386 if queried {
387 coordinates.push(x);
388 }
389 left = right;
390 }
391 if let Some(&x) = coordinates.last() {
392 coordinates.resize(coordinates.len().next_power_of_two(), x);
393 coordinates.push(x);
394 }
395
396 let mut tree = IndexedLiChaoTree::new(&coordinates);
397 let mut result = vec![None; self.queries];
398 for (i, event) in self.events.into_iter().enumerate() {
399 match event {
400 LiChaoEvent::Line(line) => tree.add_line(line),
401 LiChaoEvent::Segment(_, _, line) => {
402 let [left, right] = positions[i];
403 tree.add_segment(left as usize..right as usize, line);
404 }
405 LiChaoEvent::Query(_, output) => {
406 result[output as usize] = tree.query_min(positions[i][0] as usize);
407 }
408 }
409 }
410 result
411 }Auto Trait Implementations§
impl<'a, X, L> Freeze for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> RefUnwindSafe for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> Send for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> Sync for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> Unpin for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> UnsafeUnpin for IndexedLiChaoTree<'a, X, L>
impl<'a, X, L> UnwindSafe for IndexedLiChaoTree<'a, 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