Skip to main content

IndexedLiChaoTree

Struct IndexedLiChaoTree 

Source
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>,

Source

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    }
Source

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    }
Source

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    }
Source

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    }
Source

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>
where &'a [X]: Freeze, Vec<L>: Freeze,

§

impl<'a, X, L> RefUnwindSafe for IndexedLiChaoTree<'a, X, L>

§

impl<'a, X, L> Send for IndexedLiChaoTree<'a, X, L>
where &'a [X]: Send, Vec<L>: Send,

§

impl<'a, X, L> Sync for IndexedLiChaoTree<'a, X, L>
where &'a [X]: Sync, Vec<L>: Sync,

§

impl<'a, X, L> Unpin for IndexedLiChaoTree<'a, X, L>
where &'a [X]: Unpin, Vec<L>: Unpin,

§

impl<'a, X, L> UnsafeUnpin for IndexedLiChaoTree<'a, X, L>
where &'a [X]: UnsafeUnpin, Vec<L>: UnsafeUnpin,

§

impl<'a, X, L> UnwindSafe for IndexedLiChaoTree<'a, X, L>
where &'a [X]: UnwindSafe, Vec<L>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToArrayVecScalar for T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.