pub struct WaveletMatrixFold<'a, T, M>{
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>
impl<'a, T, M> WaveletMatrixFold<'a, T, M>
pub fn fold_lessthan(&self, val: T, range: Range<usize>) -> M::T
Sourcepub fn fold_lessthan_with_count(
&self,
val: T,
range: Range<usize>,
) -> (usize, M::T)
pub fn fold_lessthan_with_count( &self, val: T, range: Range<usize>, ) -> (usize, M::T)
Examples found in repository?
More 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}pub fn fold_range(&self, valrange: Range<T>, range: Range<usize>) -> M::T
Sourcepub fn fold_range_with_count(
&self,
valrange: Range<T>,
range: Range<usize>,
) -> (usize, M::T)
pub fn fold_range_with_count( &self, valrange: Range<T>, range: Range<usize>, ) -> (usize, M::T)
Sourcefn range_sum(&self, level: usize, range: Range<usize>) -> M::T
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 }Sourcefn fold_lessthan_indices_with_count<const N: usize>(
&self,
indices: [usize; N],
ranges: [Range<usize>; N],
bits: usize,
) -> [(usize, M::T); N]
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 }Sourcepub fn fold_lessthan_batch(
&self,
queries: impl IntoIterator<Item = (T, Range<usize>)>,
) -> Vec<M::T>
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>
impl<'a, T, M> Clone for WaveletMatrixFold<'a, T, M>
Auto Trait Implementations§
impl<'a, T, M> Freeze for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> RefUnwindSafe for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> Send for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> Sync for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> Unpin for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> UnsafeUnpin for WaveletMatrixFold<'a, T, M>
impl<'a, T, M> UnwindSafe for WaveletMatrixFold<'a, T, M>
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