nekolib/ds/
decremental_usize_set.rs1pub struct DecrementalUsizeSet {
57 u: usize,
58 len: usize,
59 small: Vec<usize>,
60 large: UnionFind,
61}
62
63const WORD_SIZE: usize = 0_usize.count_zeros() as usize;
64
65fn bsf(i: usize) -> usize { i.trailing_zeros() as usize }
66fn bsr(i: usize) -> usize { WORD_SIZE - 1 - i.leading_zeros() as usize }
67
68impl DecrementalUsizeSet {
69 pub fn new(u: usize) -> Self {
71 let mut small = vec![!0_usize; u / WORD_SIZE + 1];
72 let mut large = UnionFind::new(small.len() + 1);
73 let div = u / WORD_SIZE;
74 let rem = u % WORD_SIZE;
75 small[div] = !(!0_usize << rem);
76 if rem == 0 {
77 large.unite(div, div + 1);
78 }
79 Self { u, len: u, small, large }
80 }
81
82 pub fn universe_len(&self) -> usize { self.u }
84 pub fn len(&self) -> usize { self.len }
86 pub fn is_empty(&self) -> bool { self.len == 0 }
88
89 pub fn contains(&self, i: usize) -> bool {
91 let div = i / WORD_SIZE;
92 let rem = i % WORD_SIZE;
93 div < self.small.len() && self.small[div] >> rem & 1 != 0
94 }
95
96 pub fn less(&self, i: usize) -> Option<usize> {
98 if i == 0 {
99 None
100 } else {
101 self.less_equal(i - 1)
102 }
103 }
104 pub fn less_equal(&self, i: usize) -> Option<usize> {
106 let i = i.min(self.u - 1) + 1;
107 let div = i / WORD_SIZE;
108 let rem = i % WORD_SIZE;
109 let m = self.small[div] & !(!0_usize << rem);
110 if m != 0 {
111 return Some(div * WORD_SIZE + bsr(m));
112 }
113 let b = self.large.left(div);
114 if b == 0 {
115 None
116 } else {
117 Some((b - 1) * WORD_SIZE + bsr(self.small[b - 1]))
118 }
119 }
120 pub fn greater(&self, i: usize) -> Option<usize> {
122 if i == self.u {
123 None
124 } else {
125 self.greater_equal(i + 1)
126 }
127 }
128 pub fn greater_equal(&self, i: usize) -> Option<usize> {
130 let div = i / WORD_SIZE;
131 let rem = i % WORD_SIZE;
132 if div >= self.small.len() {
133 return None;
134 }
135 let m = self.small[div] & !0_usize << rem;
136 if m != 0 {
137 return Some(div * WORD_SIZE + bsf(m));
138 }
139 let b = self.large.right(div + 1);
140 if b == self.small.len() {
141 None
142 } else {
143 Some(b * WORD_SIZE + bsf(self.small[b]))
144 }
145 }
146
147 pub fn remove(&mut self, i: usize) -> bool {
149 let div = i / WORD_SIZE;
150 let rem = i % WORD_SIZE;
151 if div >= self.small.len() || self.small[div] >> rem & 1 == 0 {
152 return false;
153 }
154 self.len -= 1;
155 self.small[div] &= !(1_usize << rem);
156 if self.small[div] == 0 {
157 self.large.unite(div, div + 1);
158 }
159 true
160 }
161}
162
163#[derive(Clone, Copy)]
164enum Item {
165 Parent(usize),
166 Size(usize),
167}
168use Item::{Parent, Size};
169
170use std::cell::RefCell;
171
172struct UnionFind {
173 buf: RefCell<Vec<Item>>,
174 left: Vec<usize>,
175 right: Vec<usize>,
176}
177
178impl UnionFind {
179 pub fn new(n: usize) -> Self {
180 Self {
181 buf: RefCell::new(vec![Size(1); n]),
182 left: (0..n).collect(),
183 right: (0..n).collect(),
184 }
185 }
186
187 fn repr(&self, mut i: usize) -> usize {
188 let mut buf = self.buf.borrow_mut();
189 let res = {
190 let mut i = i;
191 while let Parent(ni) = buf[i] {
192 i = ni;
193 }
194 i
195 };
196 while let Parent(ni) = buf[i] {
197 buf[i] = Parent(res);
198 i = ni;
199 }
200 res
201 }
202
203 pub fn left(&self, i: usize) -> usize { self.left[self.repr(i)] }
204 pub fn right(&self, i: usize) -> usize { self.right[self.repr(i)] }
205
206 pub fn unite(&mut self, il: usize, ir: usize) {
207 let il = self.repr(il);
208 let ir = self.repr(ir);
209 let mut buf = self.buf.borrow_mut();
210 let (sl, sr) = match (buf[il], buf[ir]) {
211 (Size(sl), Size(sr)) => (sl, sr),
212 _ => unreachable!(),
213 };
214 if sl < sr {
215 buf[ir] = Size(sl + sr);
216 buf[il] = Parent(ir);
217 self.left[ir] = self.left[il];
218 } else {
219 buf[il] = Size(sl + sr);
220 buf[ir] = Parent(il);
221 self.right[il] = self.right[ir];
222 }
223 }
224}