Skip to main content

VecCompress

Struct VecCompress 

Source
pub struct VecCompress<T> {
    data: Vec<T>,
}

Fields§

§data: Vec<T>

Implementations§

Source§

impl<T> VecCompress<T>

Source

pub fn from_sorted_unique(data: Vec<T>) -> Self

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (line 546)
524    fn from_values<I: Copy>(
525        v: Vec<T>,
526        code: impl Fn(usize) -> I,
527        index: impl Fn(I) -> usize,
528        pack: impl Fn(&[I], usize) -> Vec<u64>,
529        partition: impl Fn(&[I], &[u64], usize, &mut [I]),
530    ) -> Self {
531        let len = v.len();
532        let mut sorted: Vec<_> = v
533            .into_iter()
534            .enumerate()
535            .map(|(i, value)| (value, code(i)))
536            .collect();
537        sorted.sort_unstable_by(|a, b| a.0.cmp(&b.0));
538        let mut values = Vec::with_capacity(len);
539        let mut indices = vec![code(0); len];
540        for (value, i) in sorted {
541            if values.last().is_none_or(|last| last != &value) {
542                values.push(value);
543            }
544            indices[index(i)] = code(values.len() - 1);
545        }
546        let compress = VecCompress::from_sorted_unique(values);
547        let bit_length = usize::BITS as usize - compress.size().leading_zeros() as usize;
548        let mut bit_vectors = Vec::with_capacity(bit_length);
549        let mut zeros = Vec::with_capacity(bit_length);
550        let quad_bits =
551            usize::BITS as usize - compress.size().saturating_sub(1).leading_zeros() as usize;
552        let mut quad_vectors = Vec::with_capacity(quad_bits.div_ceil(2));
553        let mut next = indices.clone();
554        for d in (0..bit_length).rev() {
555            let words = pack(&indices, d);
556            if len <= u32::MAX as usize && d < quad_bits && (d % 2 == 1 || d + 1 == quad_bits) {
557                if d % 2 == 1 {
558                    let low = pack(&indices, d - 1);
559                    quad_vectors.push(WaveletMatrixQuadVector::from_words(&low, Some(&words), len));
560                } else {
561                    quad_vectors.push(WaveletMatrixQuadVector::from_words(&words, None, len));
562                }
563            }
564            let bits = BitVector::from_words(&words, len);
565            let zero_count = bits.rank0(len);
566            if d == 0 {
567                zeros.push(zero_count);
568                bit_vectors.push(bits);
569                break;
570            }
571            partition(&indices, &words, zero_count, &mut next);
572            zeros.push(zero_count);
573            bit_vectors.push(bits);
574            mem::swap(&mut indices, &mut next);
575        }
576        Self {
577            len,
578            bit_length,
579            zeros,
580            bit_vectors,
581            quad_vectors,
582            compress,
583            #[cfg(target_arch = "x86_64")]
584            backend: match super::simd_backend() {
585                super::SimdBackend::Avx512 if !is_x86_feature_detected!("avx512vpopcntdq") => {
586                    super::SimdBackend::Avx2
587                }
588                backend => backend,
589            },
590        }
591    }
Source

pub fn values(&self) -> &[T]

Examples found in repository?
crates/competitive/src/data_structure/wavelet_matrix.rs (line 882)
874    pub fn access(&self, mut k: usize) -> T {
875        if !self.quad_vectors.is_empty() {
876            let mut index = 0;
877            for vector in &self.quad_vectors {
878                let (digit, rank) = vector.access_rank(k);
879                index = index * 4 + digit;
880                k = vector.starts[digit] + rank;
881            }
882            return self.compress.values()[index].clone();
883        }
884        let mut idx = 0;
885        for d in (0..self.bit_length - self.compress.size().is_power_of_two() as usize).rev() {
886            let level = self.level(d);
887            let (bit, rank1) = self.bit_vectors[level].access_rank1(k);
888            idx |= (bit as usize) << d;
889            k = if bit {
890                self.zeros[level] + rank1
891            } else {
892                k - rank1
893            };
894        }
895        self.compress.values()[idx].clone()
896    }
897
898    /// Returns the values at `indices` in input order.
899    pub fn access_batch(&self, indices: impl IntoIterator<Item = usize>) -> Vec<T> {
900        let indices: Vec<_> = indices.into_iter().collect();
901        let mut result = Vec::with_capacity(indices.len());
902        for indices in indices.chunks(16) {
903            let mut states = [[0; 4]; 16];
904            for (state, &index) in states.iter_mut().zip(indices) {
905                assert!(index < self.len);
906                state[0] = index;
907            }
908            self.batch::<ACCESS>(&mut states, indices.len());
909            result.extend(
910                states[..indices.len()]
911                    .iter()
912                    .map(|state| self.compress.values()[state[3]].clone()),
913            );
914        }
915        result
916    }
917
918    /// the number of val in range
919    pub fn rank(&self, val: T, range: Range<usize>) -> usize {
920        match self.compress.index_exact(&val) {
921            Some(idx) => self.range_by_index(idx, range).len(),
922            None => 0,
923        }
924    }
925
926    /// Returns the number of exact matches for each `(value, range)` query.
927    pub fn rank_batch(&self, queries: impl IntoIterator<Item = (T, Range<usize>)>) -> Vec<usize> {
928        let queries: Vec<_> = queries.into_iter().collect();
929        let mut result = Vec::with_capacity(queries.len());
930        for queries in queries.chunks(16) {
931            let mut states = [[0; 4]; 16];
932            for (state, (value, range)) in states.iter_mut().zip(queries) {
933                assert!(range.start <= range.end && range.end <= self.len);
934                if let Some(index) = self.compress.index_exact(value) {
935                    *state = [range.start, range.end, index, 0];
936                }
937            }
938            self.batch::<RANK>(&mut states, queries.len());
939            result.extend(
940                states[..queries.len()]
941                    .iter()
942                    .map(|state| state[1] - state[0]),
943            );
944        }
945        result
946    }
947
948    /// index of k-th val
949    pub fn select(&self, val: T, k: usize) -> Option<usize> {
950        let idx = self.compress.index_exact(&val)?;
951        let range = self.range_by_index(idx, 0..self.len);
952        if range.len() <= k {
953            return None;
954        }
955        let mut i = range.start + k;
956        if !self.quad_vectors.is_empty() {
957            for (level, vector) in self.quad_vectors.iter().enumerate().rev() {
958                let digit = (idx >> ((self.quad_vectors.len() - level - 1) * 2)) & 3;
959                i = vector.select(digit, i - vector.starts[digit]);
960            }
961            return Some(i);
962        }
963        for level in (self.compress.size().is_power_of_two() as usize..self.bit_length).rev() {
964            if i >= self.zeros[level] {
965                i = self.bit_vectors[level]
966                    .select1(i - self.zeros[level])
967                    .unwrap();
968            } else {
969                i = self.bit_vectors[level].select0(i).unwrap();
970            }
971        }
972        Some(i)
973    }
974
975    /// get k-th smallest value in range
976    pub fn quantile(&self, mut range: Range<usize>, mut k: usize) -> T {
977        if !self.quad_vectors.is_empty() {
978            return self.quad_quantile(range, k, 0, 0);
979        }
980        let mut idx = 0;
981        for d in (0..self.bit_length - self.compress.size().is_power_of_two() as usize).rev() {
982            let level = self.level(d);
983            let start1 = self.rank1(level, range.start);
984            let end1 = self.rank1(level, range.end);
985            let start0 = range.start - start1;
986            let end0 = range.end - end1;
987            let z = end0 - start0;
988            let bit = z <= k;
989            k -= if bit { z } else { 0 };
990            idx |= (bit as usize) << d;
991            range.start = if bit {
992                self.zeros[level] + start1
993            } else {
994                start0
995            };
996            range.end = if bit { self.zeros[level] + end1 } else { end0 };
997        }
998        self.compress.values()[idx].clone()
999    }
1000
1001    #[inline(always)]
1002    fn quad_quantile(
1003        &self,
1004        mut range: Range<usize>,
1005        mut k: usize,
1006        level: usize,
1007        mut index: usize,
1008    ) -> T {
1009        for vector in &self.quad_vectors[level..] {
1010            let start = vector.ranks(range.start);
1011            let end = vector.ranks(range.end);
1012            let mut digit = 0;
1013            while digit < 3 && k >= end[digit] - start[digit] {
1014                k -= end[digit] - start[digit];
1015                digit += 1;
1016            }
1017            index = index * 4 + digit;
1018            range = vector.starts[digit] + start[digit]..vector.starts[digit] + end[digit];
1019        }
1020        self.compress.values()[index].clone()
1021    }
1022
1023    pub fn quantile_batch(
1024        &self,
1025        queries: impl IntoIterator<Item = (Range<usize>, usize)>,
1026    ) -> Vec<T> {
1027        let queries: Vec<_> = queries.into_iter().collect();
1028        let mut result = Vec::with_capacity(queries.len());
1029        for queries in queries.chunks(16) {
1030            let mut states = [[0; 4]; 16];
1031            for (state, (range, k)) in states.iter_mut().zip(queries) {
1032                assert!(range.start <= range.end && range.end <= self.len && *k < range.len());
1033                *state = [range.start, range.end, *k, 0];
1034            }
1035            if let [(range, k)] = queries {
1036                result.push(self.quantile(range.clone(), *k));
1037                continue;
1038            }
1039            self.batch::<QUANTILE>(&mut states, queries.len());
1040            result.extend(
1041                states[..queries.len()]
1042                    .iter()
1043                    .map(|state| self.compress.values()[state[3]].clone()),
1044            );
1045        }
1046        result
1047    }
1048
1049    /// Returns the requested order statistics of one range. `ranks` must be sorted
1050    /// in nondecreasing order and every rank must be less than the range length.
1051    pub fn quantiles_sorted(&self, range: Range<usize>, ranks: &[usize]) -> Vec<T> {
1052        assert!(range.start <= range.end && range.end <= self.len);
1053        assert!(ranks.windows(2).all(|pair| pair[0] <= pair[1]));
1054        assert!(ranks.last().is_none_or(|&k| k < range.len()));
1055        if ranks.is_empty() {
1056            return Vec::new();
1057        }
1058        if ranks[0] == ranks[ranks.len() - 1] {
1059            return vec![self.quantile(range, ranks[0]); ranks.len()];
1060        }
1061        let use_batch = ranks.len() < 1024;
1062        #[cfg(target_arch = "x86_64")]
1063        let use_batch = use_batch || self.backend == super::SimdBackend::Avx512;
1064        // Sparse requests amortize less of the shared traversal's branching work.
1065        if use_batch && ranks.len() < self.compress.size().div_ceil(16) {
1066            return self.quantile_batch(ranks.iter().map(|&k| (range.clone(), k)));
1067        }
1068        let mut result = Vec::with_capacity(ranks.len());
1069        if !self.quad_vectors.is_empty() {
1070            let mut stack = vec![(range, 0, 0, 0, ranks)];
1071            while let Some((range, base, index, level, ranks)) = stack.pop() {
1072                if level == self.quad_vectors.len() {
1073                    result.resize(
1074                        result.len() + ranks.len(),
1075                        self.compress.values()[index].clone(),
1076                    );
1077                    continue;
1078                }
1079                if ranks.len() == 1 {
1080                    result.push(self.quad_quantile(range, ranks[0] - base, level, index));
1081                    continue;
1082                }
1083                let vector = &self.quad_vectors[level];
1084                let start = vector.ranks(range.start);
1085                let end = vector.ranks(range.end);
1086                let mut split = base + range.len();
1087                let mut requested = ranks.len();
1088                for digit in (0..4).rev() {
1089                    split -= end[digit] - start[digit];
1090                    let boundary = ranks[..requested].partition_point(|&k| k < split);
1091                    if boundary < requested {
1092                        stack.push((
1093                            vector.starts[digit] + start[digit]..vector.starts[digit] + end[digit],
1094                            split,
1095                            index * 4 + digit,
1096                            level + 1,
1097                            &ranks[boundary..requested],
1098                        ));
1099                    }
1100                    requested = boundary;
1101                }
1102            }
1103            return result;
1104        }
1105        let mut stack = vec![(range, 0, 0, self.bit_length, ranks)];
1106        while let Some((range, base, index, bits, ranks)) = stack.pop() {
1107            if bits == 0 {
1108                result.resize(
1109                    result.len() + ranks.len(),
1110                    self.compress.values()[index].clone(),
1111                );
1112                continue;
1113            }
1114            let d = bits - 1;
1115            let level = self.level(d);
1116            let start1 = self.rank1(level, range.start);
1117            let end1 = self.rank1(level, range.end);
1118            let start0 = range.start - start1;
1119            let end0 = range.end - end1;
1120            let split = base + end0 - start0;
1121            let boundary = ranks.partition_point(|&k| k < split);
1122            if boundary < ranks.len() {
1123                stack.push((
1124                    self.zeros[level] + start1..self.zeros[level] + end1,
1125                    split,
1126                    index | (1 << d),
1127                    d,
1128                    &ranks[boundary..],
1129                ));
1130            }
1131            if boundary != 0 {
1132                stack.push((start0..end0, base, index, d, &ranks[..boundary]));
1133            }
1134        }
1135        result
1136    }
1137
1138    /// get k-th smallest value out of range
1139    pub fn quantile_outer(&self, mut range: Range<usize>, mut k: usize) -> T {
1140        if !self.quad_vectors.is_empty() {
1141            let mut outer = 0..self.len;
1142            let mut index = 0;
1143            for vector in &self.quad_vectors {
1144                let start = vector.ranks(range.start);
1145                let end = vector.ranks(range.end);
1146                let outer_start = vector.ranks(outer.start);
1147                let outer_end = vector.ranks(outer.end);
1148                let mut digit = 0;
1149                while digit < 3 {
1150                    let count = outer_end[digit] - outer_start[digit] - (end[digit] - start[digit]);
1151                    if k < count {
1152                        break;
1153                    }
1154                    k -= count;
1155                    digit += 1;
1156                }
1157                index = index * 4 + digit;
1158                range = vector.starts[digit] + start[digit]..vector.starts[digit] + end[digit];
1159                outer = vector.starts[digit] + outer_start[digit]
1160                    ..vector.starts[digit] + outer_end[digit];
1161            }
1162            return self.compress.values()[index].clone();
1163        }
1164        let mut idx = 0;
1165        let mut orange = 0..self.len;
1166        for d in (0..self.bit_length - self.compress.size().is_power_of_two() as usize).rev() {
1167            let level = self.level(d);
1168            let range_start1 = self.rank1(level, range.start);
1169            let range_end1 = self.rank1(level, range.end);
1170            let outer_start1 = self.rank1(level, orange.start);
1171            let outer_end1 = self.rank1(level, orange.end);
1172            let range_start0 = range.start - range_start1;
1173            let range_end0 = range.end - range_end1;
1174            let outer_start0 = orange.start - outer_start1;
1175            let outer_end0 = orange.end - outer_end1;
1176            let z = (outer_end0 - outer_start0) - (range_end0 - range_start0);
1177            if z <= k {
1178                k -= z;
1179                idx |= 1 << d;
1180                range.start = self.zeros[level] + range_start1;
1181                range.end = self.zeros[level] + range_end1;
1182                orange.start = self.zeros[level] + outer_start1;
1183                orange.end = self.zeros[level] + outer_end1;
1184            } else {
1185                range.start = range_start0;
1186                range.end = range_end0;
1187                orange.start = outer_start0;
1188                orange.end = outer_end0;
1189            }
1190        }
1191        self.compress.values()[idx].clone()
1192    }

Trait Implementations§

Source§

impl<T: Clone> Clone for VecCompress<T>

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<T> Compressor<T> for VecCompress<T>
where T: Ord,

Source§

fn index_exact(&self, index: &T) -> Option<usize>

Source§

fn size(&self) -> usize

Source§

impl<T: Debug> Debug for VecCompress<T>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<T> FromIterator<T> for VecCompress<T>
where T: Ord,

Source§

fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item = T>,

Creates a value from an iterator. Read more
Source§

impl<T> OrderedCompressor<T> for VecCompress<T>
where T: Ord,

Source§

fn index_lower_bound(&self, index: &T) -> usize

Auto Trait Implementations§

§

impl<T> Freeze for VecCompress<T>
where Vec<T>: Freeze,

§

impl<T> RefUnwindSafe for VecCompress<T>
where Vec<T>: RefUnwindSafe,

§

impl<T> Send for VecCompress<T>
where Vec<T>: Send,

§

impl<T> Sync for VecCompress<T>
where Vec<T>: Sync,

§

impl<T> Unpin for VecCompress<T>
where Vec<T>: Unpin,

§

impl<T> UnsafeUnpin for VecCompress<T>
where Vec<T>: UnsafeUnpin,

§

impl<T> UnwindSafe for VecCompress<T>
where Vec<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.