Skip to main content

nekolib/ds/
decremental_usize_set.rs

1//! `usize` の decremental set。
2
3/// `usize` の decremental set。
4///
5/// $\\{0, 1, \\dots, u-1\\}$ で初期化し、要素を取り除く操作を行える。
6///
7/// # Complexity
8/// |演算|時間計算量|
9/// |---|---|
10/// |`new`|$\\Theta(n/w)$|
11/// |`remove`|amortized $O(1)$|
12/// |`less`|amortized $O(1)$|
13/// |`less_equal`|amortized $O(1)$|
14/// |`greater`|amortized $O(1)$|
15/// |`greater_equal`|amortized $O(1)$|
16///
17/// 空間:$O(n)$ bits.
18///
19/// # References
20/// - <https://atcoder.jp/contests/abc228/editorial/2962>
21/// - <https://twitter.com/noshi91/status/1389116169634795525>
22///
23/// # Examples
24/// ```
25/// use nekolib::ds::DecrementalUsizeSet;
26///
27/// let mut set = DecrementalUsizeSet::new(6);
28/// assert_eq!(set.universe_len(), 6);
29/// assert_eq!(set.len(), 6);
30///
31/// set.remove(3);
32/// assert_eq!(set.less(3), Some(2));
33/// assert_eq!(set.less_equal(3), Some(2));
34/// assert_eq!(set.greater(3), Some(4));
35/// assert_eq!(set.greater_equal(3), Some(4));
36///
37/// assert_eq!(set.less(4), Some(2));
38/// assert_eq!(set.less_equal(4), Some(4));
39/// assert_eq!(set.greater(4), Some(5));
40/// assert_eq!(set.greater_equal(4), Some(4));
41///
42/// assert_eq!(set.less(0), None);
43/// assert_eq!(set.greater(5), None);
44///
45/// set.remove(0);
46/// set.remove(5);
47/// assert_eq!(set.less_equal(0), None);
48/// assert_eq!(set.greater_equal(5), None);
49///
50/// assert!(set.contains(4));
51/// assert!(!set.contains(3));
52///
53/// assert_eq!(set.universe_len(), 6);
54/// assert_eq!(set.len(), 3);
55/// ```
56pub 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    /// $S\\gets\\{0, 1, \\dots, u-1\\}$ で初期化。
70    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    /// $u$ を返す。
83    pub fn universe_len(&self) -> usize { self.u }
84    /// $|S|$ を返す。
85    pub fn len(&self) -> usize { self.len }
86    /// $S=\\emptyset$ を返す。
87    pub fn is_empty(&self) -> bool { self.len == 0 }
88
89    /// $i\\in S$ を返す。
90    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    /// $\\max\_{j\\lt i}\\text{ s.t. }j\\in S$ を返す。
97    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    /// $\\max\_{j\\le i}\\text{ s.t. }j\\in S$ を返す。
105    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    /// $\\min\_{j\\gt i}\\text{ s.t. }j\\in S$ を返す。
121    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    /// $\\min\_{j\\ge i}\\text{ s.t. }j\\in S$ を返す。
129    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    /// $S\\gets S\\setminus\\{i\\}$ で更新する。
148    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}