Skip to main content

WaveletMatrixFold

Struct WaveletMatrixFold 

Source
pub struct WaveletMatrixFold<'a, T, M>
where T: Ord + Clone, M: AbelianGroup,
{ wavelet_matrix: &'a WaveletMatrix<T>, prefix: Vec<M::T>, offsets: Vec<usize>, }

Fields§

§wavelet_matrix: &'a WaveletMatrix<T>§prefix: Vec<M::T>§offsets: Vec<usize>

Implementations§

Source§

impl<'a, T, M> WaveletMatrixFold<'a, T, M>
where T: Ord + Clone, M: AbelianGroup,

Source

pub fn fold_lessthan(&self, val: T, range: Range<usize>) -> M::T

Source

pub fn fold_lessthan_with_count( &self, val: T, range: Range<usize>, ) -> (usize, M::T)

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (line 1590)
1589    pub fn fold_lessthan(&self, val: T, range: Range<usize>) -> M::T {
1590        self.fold_lessthan_with_count(val, range).1
1591    }
More examples
Hide additional examples
crates/library_checker/src/data_structure/static_range_sum_with_upper_bound.rs (line 30)
22pub fn static_range_sum_with_upper_bound_wavelet_matrix(reader: impl Read, writer: impl Write) {
23    prepare_io!(reader, writer);
24    sc!(n, q, a: [i64; n]);
25    let weights = a.clone();
26    let wm = WaveletMatrix::new(a);
27    let fold = wm.build_fold::<AdditiveOperation<i64>>(&weights);
28    for _ in 0..q {
29        sc!(l, r, x: i64);
30        let (count, sum) = fold.fold_lessthan_with_count(x + 1, l..r);
31        pp!(count, sum);
32    }
33}
Source

pub fn fold_range(&self, valrange: Range<T>, range: Range<usize>) -> M::T

Source

pub fn fold_range_with_count( &self, valrange: Range<T>, range: Range<usize>, ) -> (usize, M::T)

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (line 1604)
1603    pub fn fold_range(&self, valrange: Range<T>, range: Range<usize>) -> M::T {
1604        self.fold_range_with_count(valrange, range).1
1605    }
Source

fn range_sum(&self, level: usize, range: Range<usize>) -> M::T

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (line 1648)
1607    pub fn fold_range_with_count(
1608        &self,
1609        valrange: Range<T>,
1610        mut range: Range<usize>,
1611    ) -> (usize, M::T) {
1612        debug_assert!(range.end <= self.wavelet_matrix.len);
1613        let lower = self
1614            .wavelet_matrix
1615            .compress
1616            .index_lower_bound(&valrange.start);
1617        let upper = self
1618            .wavelet_matrix
1619            .compress
1620            .index_lower_bound(&valrange.end);
1621        if lower >= upper {
1622            return (0, M::unit());
1623        }
1624        for d in (0..self.wavelet_matrix.bit_length).rev() {
1625            let level = self.wavelet_matrix.level(d);
1626            let start1 = self.wavelet_matrix.bit_vectors[level].rank1(range.start);
1627            let end1 = self.wavelet_matrix.bit_vectors[level].rank1(range.end);
1628            let start0 = range.start - start1;
1629            let end0 = range.end - end1;
1630            if ((lower >> d) & 1) == ((upper >> d) & 1) {
1631                if ((lower >> d) & 1) == 0 {
1632                    range = start0..end0;
1633                } else {
1634                    range = self.wavelet_matrix.zeros[level] + start1
1635                        ..self.wavelet_matrix.zeros[level] + end1;
1636                }
1637                continue;
1638            }
1639            let zero_range = start0..end0;
1640            let one_range =
1641                self.wavelet_matrix.zeros[level] + start1..self.wavelet_matrix.zeros[level] + end1;
1642            let [(lower_count, lower_sum), (upper_count, upper_sum)] = self
1643                .fold_lessthan_indices_with_count(
1644                    [lower, upper],
1645                    [zero_range.clone(), one_range],
1646                    d,
1647                );
1648            let zero_sum = self.range_sum(level, zero_range.clone());
1649            return (
1650                zero_range.len() - lower_count + upper_count,
1651                M::operate(&M::rinv_operate(&zero_sum, &lower_sum), &upper_sum),
1652            );
1653        }
1654        (0, M::unit())
1655    }
1656
1657    #[inline]
1658    fn range_sum(&self, level: usize, range: Range<usize>) -> M::T {
1659        let offset = self.offsets[level];
1660        M::rinv_operate(
1661            &self.prefix[offset + range.end],
1662            &self.prefix[offset + range.start],
1663        )
1664    }
1665
1666    fn fold_lessthan_indices_with_count<const N: usize>(
1667        &self,
1668        indices: [usize; N],
1669        mut ranges: [Range<usize>; N],
1670        bits: usize,
1671    ) -> [(usize, M::T); N] {
1672        let mut results = std::array::from_fn(|_| (0, M::unit()));
1673        let last = indices
1674            .iter()
1675            .map(|index| index.trailing_zeros() as usize)
1676            .min()
1677            .unwrap_or(bits);
1678        for d in (last..bits).rev() {
1679            let level = self.wavelet_matrix.level(d);
1680            for ((&index, range), (count, sum)) in indices.iter().zip(&mut ranges).zip(&mut results)
1681            {
1682                let start1 = self.wavelet_matrix.bit_vectors[level].rank1(range.start);
1683                let end1 = self.wavelet_matrix.bit_vectors[level].rank1(range.end);
1684                let start0 = range.start - start1;
1685                let end0 = range.end - end1;
1686                if ((index >> d) & 1) != 0 {
1687                    *count += end0 - start0;
1688                    M::operate_assign(sum, &self.range_sum(level, start0..end0));
1689                    range.start = self.wavelet_matrix.zeros[level] + start1;
1690                    range.end = self.wavelet_matrix.zeros[level] + end1;
1691                } else {
1692                    range.start = start0;
1693                    range.end = end0;
1694                }
1695            }
1696        }
1697        results
1698    }
Source

fn fold_lessthan_indices_with_count<const N: usize>( &self, indices: [usize; N], ranges: [Range<usize>; N], bits: usize, ) -> [(usize, M::T); N]

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (lines 1595-1599)
1593    pub fn fold_lessthan_with_count(&self, val: T, range: Range<usize>) -> (usize, M::T) {
1594        debug_assert!(range.end <= self.wavelet_matrix.len);
1595        let [result] = self.fold_lessthan_indices_with_count(
1596            [self.wavelet_matrix.compress.index_lower_bound(&val)],
1597            [range],
1598            self.wavelet_matrix.bit_length,
1599        );
1600        result
1601    }
1602
1603    pub fn fold_range(&self, valrange: Range<T>, range: Range<usize>) -> M::T {
1604        self.fold_range_with_count(valrange, range).1
1605    }
1606
1607    pub fn fold_range_with_count(
1608        &self,
1609        valrange: Range<T>,
1610        mut range: Range<usize>,
1611    ) -> (usize, M::T) {
1612        debug_assert!(range.end <= self.wavelet_matrix.len);
1613        let lower = self
1614            .wavelet_matrix
1615            .compress
1616            .index_lower_bound(&valrange.start);
1617        let upper = self
1618            .wavelet_matrix
1619            .compress
1620            .index_lower_bound(&valrange.end);
1621        if lower >= upper {
1622            return (0, M::unit());
1623        }
1624        for d in (0..self.wavelet_matrix.bit_length).rev() {
1625            let level = self.wavelet_matrix.level(d);
1626            let start1 = self.wavelet_matrix.bit_vectors[level].rank1(range.start);
1627            let end1 = self.wavelet_matrix.bit_vectors[level].rank1(range.end);
1628            let start0 = range.start - start1;
1629            let end0 = range.end - end1;
1630            if ((lower >> d) & 1) == ((upper >> d) & 1) {
1631                if ((lower >> d) & 1) == 0 {
1632                    range = start0..end0;
1633                } else {
1634                    range = self.wavelet_matrix.zeros[level] + start1
1635                        ..self.wavelet_matrix.zeros[level] + end1;
1636                }
1637                continue;
1638            }
1639            let zero_range = start0..end0;
1640            let one_range =
1641                self.wavelet_matrix.zeros[level] + start1..self.wavelet_matrix.zeros[level] + end1;
1642            let [(lower_count, lower_sum), (upper_count, upper_sum)] = self
1643                .fold_lessthan_indices_with_count(
1644                    [lower, upper],
1645                    [zero_range.clone(), one_range],
1646                    d,
1647                );
1648            let zero_sum = self.range_sum(level, zero_range.clone());
1649            return (
1650                zero_range.len() - lower_count + upper_count,
1651                M::operate(&M::rinv_operate(&zero_sum, &lower_sum), &upper_sum),
1652            );
1653        }
1654        (0, M::unit())
1655    }
1656
1657    #[inline]
1658    fn range_sum(&self, level: usize, range: Range<usize>) -> M::T {
1659        let offset = self.offsets[level];
1660        M::rinv_operate(
1661            &self.prefix[offset + range.end],
1662            &self.prefix[offset + range.start],
1663        )
1664    }
1665
1666    fn fold_lessthan_indices_with_count<const N: usize>(
1667        &self,
1668        indices: [usize; N],
1669        mut ranges: [Range<usize>; N],
1670        bits: usize,
1671    ) -> [(usize, M::T); N] {
1672        let mut results = std::array::from_fn(|_| (0, M::unit()));
1673        let last = indices
1674            .iter()
1675            .map(|index| index.trailing_zeros() as usize)
1676            .min()
1677            .unwrap_or(bits);
1678        for d in (last..bits).rev() {
1679            let level = self.wavelet_matrix.level(d);
1680            for ((&index, range), (count, sum)) in indices.iter().zip(&mut ranges).zip(&mut results)
1681            {
1682                let start1 = self.wavelet_matrix.bit_vectors[level].rank1(range.start);
1683                let end1 = self.wavelet_matrix.bit_vectors[level].rank1(range.end);
1684                let start0 = range.start - start1;
1685                let end0 = range.end - end1;
1686                if ((index >> d) & 1) != 0 {
1687                    *count += end0 - start0;
1688                    M::operate_assign(sum, &self.range_sum(level, start0..end0));
1689                    range.start = self.wavelet_matrix.zeros[level] + start1;
1690                    range.end = self.wavelet_matrix.zeros[level] + end1;
1691                } else {
1692                    range.start = start0;
1693                    range.end = end0;
1694                }
1695            }
1696        }
1697        results
1698    }
1699
1700    /// Folds the weights below each query's threshold, traversing the queries together.
1701    pub fn fold_lessthan_batch(
1702        &self,
1703        queries: impl IntoIterator<Item = (T, Range<usize>)>,
1704    ) -> Vec<M::T> {
1705        let queries: Vec<_> = queries.into_iter().collect();
1706        let mut result = Vec::with_capacity(queries.len());
1707        for queries in queries.chunks(16) {
1708            let mut indices = [0; 16];
1709            let mut ranges = std::array::from_fn(|_| 0..0);
1710            for (i, (value, range)) in queries.iter().enumerate() {
1711                assert!(range.start <= range.end && range.end <= self.wavelet_matrix.len);
1712                indices[i] = self.wavelet_matrix.compress.index_lower_bound(value);
1713                ranges[i] = range.clone();
1714            }
1715            result.extend(
1716                self.fold_lessthan_indices_with_count(
1717                    indices,
1718                    ranges,
1719                    self.wavelet_matrix.bit_length,
1720                )
1721                .into_iter()
1722                .take(queries.len())
1723                .map(|(_, sum)| sum),
1724            );
1725        }
1726        result
1727    }
Source

pub fn fold_lessthan_batch( &self, queries: impl IntoIterator<Item = (T, Range<usize>)>, ) -> Vec<M::T>

Folds the weights below each query’s threshold, traversing the queries together.

Examples found in repository?
crates/library_checker/src/data_structure/rectangle_sum.rs (lines 22-27)
9pub fn rectangle_sum(reader: impl Read, writer: impl Write) {
10    prepare_io!(buffered; reader, writer);
11    sc!(n, q, mut xyw: [(u32, u32, i64); n], queries: [(u32, u32, u32, u32); q]);
12    xyw.radix_sort_by_key(|&(x, ..)| x);
13    let xs: Vec<_> = xyw.iter().map(|&(x, ..)| x).collect();
14    let search = StaticSearch::from_sorted(&xs);
15    let endpoints: Vec<_> = queries.iter().flat_map(|&(l, _, r, _)| [l, r]).collect();
16    let mut positions = vec![0; endpoints.len()];
17    search.lower_bound_batch(&endpoints, &mut positions);
18    let ys = xyw.iter().map(|&(_, y, _)| y).collect();
19    let weights: Vec<_> = xyw.iter().map(|&(_, _, w)| w).collect();
20    let wm = WaveletMatrix::new(ys);
21    let fold = wm.build_fold::<AdditiveOperation<i64>>(&weights);
22    let result = fold.fold_lessthan_batch(
23        queries
24            .into_iter()
25            .zip(positions.as_chunks::<2>().0)
26            .flat_map(|((_, d, _, u), &[l, r])| [(d, l..r), (u, l..r)]),
27    );
28    for &[lower, upper] in result.as_chunks::<2>().0 {
29        pp!(upper - lower);
30    }
31}

Trait Implementations§

Source§

impl<'a, T, M> Clone for WaveletMatrixFold<'a, T, M>
where T: Ord + Clone + Clone, M: AbelianGroup + Clone, M::T: Clone,

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a, T, M> Debug for WaveletMatrixFold<'a, T, M>
where T: Ord + Clone + Debug, M: AbelianGroup + Debug, M::T: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, T, M> Freeze for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: Freeze, Vec<<M as Magma>::T>: Freeze,

§

impl<'a, T, M> RefUnwindSafe for WaveletMatrixFold<'a, T, M>

§

impl<'a, T, M> Send for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: Send, Vec<<M as Magma>::T>: Send,

§

impl<'a, T, M> Sync for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: Sync, Vec<<M as Magma>::T>: Sync,

§

impl<'a, T, M> Unpin for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: Unpin, Vec<<M as Magma>::T>: Unpin,

§

impl<'a, T, M> UnsafeUnpin for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: UnsafeUnpin, Vec<<M as Magma>::T>: UnsafeUnpin,

§

impl<'a, T, M> UnwindSafe for WaveletMatrixFold<'a, T, M>
where &'a WaveletMatrix<T>: UnwindSafe, Vec<<M as Magma>::T>: 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.