dsalgo/
xor_prefix_set_hash.rs1use std::collections::{
2 HashMap,
3 HashSet,
4};
5
6use crate::rng_static_xorshift64::*;
7
8pub struct PrefixSetHash<T>(HashMap<T, u64>);
12
13impl<T: Clone + std::hash::Hash + Eq> PrefixSetHash<T> {
14 pub fn new() -> Self {
15 Self(HashMap::new())
16 }
17
18 pub fn calc(
19 &mut self,
20 a: &[T],
21 ) -> Vec<u64> {
22 let mut s = HashSet::new();
23
24 let mut b: Vec<_> = a
25 .iter()
26 .map(|x| {
27 let v = self
28 .0
29 .entry(x.clone())
30 .or_insert_with(|| static_xorshift64());
31
32 if s.contains(x) {
33 0
34 } else {
35 s.insert(x.clone());
36
37 *v
38 }
39 })
40 .collect();
41
42 for i in 0..a.len() - 1 {
43 b[i + 1] ^= b[i];
44 }
45
46 b
47 }
48}
49
50#[cfg(test)]
51
52mod tests {
53
54 use super::*;
55
56 #[test]
57
58 fn test() {
59 let a = vec![1, 2, 3, 4, 5];
61
62 let b = vec![1, 2, 2, 4, 3];
63
64 let q = vec![
65 ((1, 1), true),
66 ((2, 2), true),
67 ((2, 3), true),
68 ((3, 3), false),
69 ((4, 4), false),
70 ((4, 5), true),
71 ((5, 5), false),
72 ];
73
74 let mut hash = PrefixSetHash::new();
75
76 let a = hash.calc(&a);
77
78 let b = hash.calc(&b);
79
80 for ((i, j), ans) in q {
81 let i = i - 1;
82
83 let j = j - 1;
84
85 assert_eq!(a[i] == b[j], ans);
86 }
87 }
88}