competitive/data_structure/
range_frequency.rs1use super::{AdditiveOperation, BinaryIndexedTree};
2use std::{collections::HashMap, hash::Hash, mem::replace};
3
4#[derive(Debug, Clone)]
5enum RangeFrequencyQuery {
6 Add {
7 index: usize,
8 },
9 Remove {
10 index: usize,
11 },
12 Query {
13 left: usize,
14 right: usize,
15 output_index: usize,
16 },
17}
18
19#[derive(Debug, Clone)]
20pub struct RangeFrequency<T>
21where
22 T: Clone + Eq + Hash,
23{
24 array: Vec<T>,
25 queries: HashMap<T, Vec<RangeFrequencyQuery>>,
26 output_size: usize,
27}
28
29impl<T> RangeFrequency<T>
30where
31 T: Clone + Eq + Hash,
32{
33 pub fn new(array: Vec<T>) -> Self {
34 let mut queries = HashMap::<T, Vec<RangeFrequencyQuery>>::new();
35 for (index, value) in array.iter().cloned().enumerate() {
36 queries
37 .entry(value)
38 .or_default()
39 .push(RangeFrequencyQuery::Add { index });
40 }
41 Self {
42 array,
43 queries,
44 output_size: 0,
45 }
46 }
47
48 pub fn set(&mut self, index: usize, value: T) {
49 let old_value = replace(&mut self.array[index], value);
50 self.queries
51 .entry(old_value)
52 .or_default()
53 .push(RangeFrequencyQuery::Remove { index });
54 self.queries
55 .entry(self.array[index].clone())
56 .or_default()
57 .push(RangeFrequencyQuery::Add { index });
58 }
59
60 pub fn query(&mut self, left: usize, right: usize, value: T) -> usize {
61 let output_index = self.output_size;
62 self.queries
63 .entry(value)
64 .or_default()
65 .push(RangeFrequencyQuery::Query {
66 left,
67 right,
68 output_index,
69 });
70 self.output_size += 1;
71 output_index
72 }
73
74 pub fn execute_with_callback(mut self, mut callback: impl FnMut(usize, usize)) {
75 let mut processor = RangeFrequencyProcessor::new(self.array.len());
76 for (index, value) in self.array.into_iter().enumerate() {
77 self.queries
78 .entry(value)
79 .or_default()
80 .push(RangeFrequencyQuery::Remove { index });
81 }
82 for (_, queries) in self.queries {
83 for query in queries {
84 match query {
85 RangeFrequencyQuery::Add { index } => {
86 processor.add(index);
87 }
88 RangeFrequencyQuery::Remove { index } => {
89 processor.remove(index);
90 }
91 RangeFrequencyQuery::Query {
92 left,
93 right,
94 output_index,
95 } => {
96 callback(output_index, processor.query(left, right));
97 }
98 }
99 }
100 }
101 }
102
103 pub fn execute(self) -> Vec<usize> {
104 let mut results = vec![0; self.output_size];
105 self.execute_with_callback(|i, v| results[i] = v);
106 results
107 }
108}
109
110#[derive(Debug, Clone)]
111struct RangeFrequencyProcessor {
112 bit: BinaryIndexedTree<AdditiveOperation<i32>>,
113 data: Vec<u64>,
114}
115
116impl RangeFrequencyProcessor {
117 fn new(size: usize) -> Self {
118 Self {
119 bit: BinaryIndexedTree::new(size.div_ceil(64)),
120 data: vec![0; size.div_ceil(64)],
121 }
122 }
123
124 fn add(&mut self, index: usize) {
125 let (block, bit) = (index / 64, index % 64);
126 assert!(self.data[block] & (1 << bit) == 0);
127 self.data[block] |= 1 << bit;
128 self.bit.update(block, 1);
129 }
130
131 fn remove(&mut self, index: usize) {
132 let (i, j) = (index / 64, index % 64);
133 assert!(self.data[i] & (1 << j) != 0);
134 self.data[i] &= !(1 << j);
135 self.bit.update(i, -1);
136 }
137
138 fn query(&self, left: usize, right: usize) -> usize {
139 if left >= right {
140 return 0;
141 }
142 let right = right - 1;
143 let (li, lj) = (left / 64, left % 64);
144 let (ri, rj) = (right / 64, right % 64);
145 let rj_r = 63 - rj;
146 if li == ri {
147 (self.data[li] << rj_r >> (lj + rj_r)).count_ones() as usize
148 } else {
149 let mut ans = self.bit.fold(li + 1, ri) as usize;
150 ans += (self.data[li] >> lj).count_ones() as usize;
151 ans += (self.data[ri] << rj_r).count_ones() as usize;
152 ans
153 }
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160 use crate::{
161 rand,
162 tools::{NotEmptySegment as Nes, Xorshift},
163 };
164
165 #[test]
166 fn test_range_frequency() {
167 let mut rng = Xorshift::default();
168 for _ in 0..100 {
169 rand!(rng, n: 1..200, mut a: [0..10; n]);
170 let mut rf = RangeFrequency::new(a.clone());
171 for _ in 0..100 {
172 rand!(rng, i: 0..n, v: 0..10);
173 rf.set(i, v);
174 a[i] = v;
175 }
176 let mut expected = vec![];
177 for _ in 0..100 {
178 let (l, r) = rng.random(Nes(n));
179 for v in 0..10 {
180 expected.push(a[l..r].iter().filter(|&&x| x == v).count());
181 rf.query(l, r, v);
182 }
183 }
184 let result = rf.execute();
185 assert_eq!(result, expected);
186 }
187 }
188}