competitive_library/structure/
segment_tree.rs1use std::cmp::max;
3use std::cmp::min;
4
5pub trait Monoid {
6 type T: Clone;
7 fn identity_element() -> Self::T;
8 fn binary_operation(a: &Self::T, b: &Self::T) -> Self::T;
9}
10pub struct Min {}
11impl Monoid for Min {
12 type T = i64;
13 #[inline]
14 fn identity_element() -> Self::T {
15 i32::MAX as i64
16 }
17 #[inline]
18 fn binary_operation(a: &Self::T, b: &Self::T) -> Self::T {
19 min(*a, *b)
20 }
21}
22pub struct Max {}
23impl Monoid for Max {
24 type T = i64;
25 #[inline]
26 fn identity_element() -> Self::T {
27 i64::MIN
28 }
29 #[inline]
30 fn binary_operation(a: &Self::T, b: &Self::T) -> Self::T {
31 max(*a, *b)
32 }
33}
34
35pub struct SegmentTree<M>
36where
37 M: Monoid,
38{
39 n: usize,
40 size: usize,
41 log: usize,
42 data: Vec<M::T>,
43}
44impl<M: Monoid> SegmentTree<M> {
45 pub fn new(n: usize) -> SegmentTree<M> {
46 vec![M::identity_element(); n].into()
47 }
48}
49impl<M: Monoid> From<Vec<M::T>> for SegmentTree<M> {
50 fn from(v: Vec<M::T>) -> Self {
51 let n = v.len();
52 let log = (32 - (n as u32).saturating_sub(1).leading_zeros()) as usize;
53 let size = 1 << log;
54 let data = {
55 let mut data = vec![M::identity_element(); 2 * size];
56 data[size..(size + n)].clone_from_slice(&v);
57 data
58 };
59 {
60 let mut sg = SegmentTree { n, size, log, data };
61 (1..size).rev().for_each(|i| sg.update(i));
62 sg
63 }
64 }
65}
66impl<M: Monoid> SegmentTree<M> {
67 pub fn query(&self, mut l: usize, mut r: usize) -> M::T {
68 let (mut sml, mut smr) = (M::identity_element(), M::identity_element());
69 l += self.size;
70 r += self.size;
71
72 while l < r {
73 if l & 1 != 0 {
74 sml = M::binary_operation(&sml, unsafe { self.data.get_unchecked(l) });
75 l += 1;
76 }
77 if r & 1 != 0 {
78 r -= 1;
79 smr = M::binary_operation(unsafe { self.data.get_unchecked(r) }, &smr);
80 }
81 l >>= 1;
82 r >>= 1;
83 }
84
85 M::binary_operation(&sml, &smr)
86 }
87 fn update(&mut self, k: usize) {
88 *unsafe { self.data.get_unchecked_mut(k) } =
89 M::binary_operation(unsafe { self.data.get_unchecked(2 * k) }, unsafe {
90 self.data.get_unchecked(2 * k + 1)
91 });
92 }
93 pub fn set(&mut self, mut p: usize, x: M::T) {
94 p += self.size;
95 self.data[p] = x;
96 (1..=self.log).for_each(|i| self.update(p >> i));
97 }
98 pub fn get(&self, i: usize) -> M::T {
99 self.data[i].clone()
100 }
101 pub fn max_right<F>(&self, mut l: usize, f: F) -> usize
102 where
103 F: Fn(&M::T) -> bool,
104 {
105 assert!(l <= self.n);
106 assert!(f(&M::identity_element()));
107 if l == self.n {
108 return self.n;
109 }
110 l += self.size;
111 let mut sm = M::identity_element();
112 loop {
113 while l % 2 == 0 {
115 l >>= 1;
116 }
117 if !f(&M::binary_operation(&sm, unsafe {
118 self.data.get_unchecked(l)
119 })) {
120 while l < self.size {
121 l *= 2;
122 let res = M::binary_operation(&sm, unsafe { self.data.get_unchecked(l) });
123 if f(&res) {
124 sm = res;
125 l += 1;
126 }
127 }
128 return l - self.size;
129 }
130 sm = M::binary_operation(&sm, unsafe { self.data.get_unchecked(l) });
131 l += 1;
132 let l = l as isize;
135 if (l & -l) == l {
136 break;
137 }
138 }
139 self.n
140 }
141
142 pub fn min_left<F>(&self, mut r: usize, f: F) -> usize
143 where
144 F: Fn(&M::T) -> bool,
145 {
146 assert!(r <= self.n);
147 assert!(f(&M::identity_element()));
148 if r == 0 {
149 return 0;
150 }
151 r += self.size;
152 let mut sm = M::identity_element();
153 loop {
154 r -= 1;
156 while r > 1 && r % 2 == 1 {
157 r >>= 1;
158 }
159 if !f(&M::binary_operation(
160 unsafe { self.data.get_unchecked(r) },
161 &sm,
162 )) {
163 while r < self.size {
164 r = 2 * r + 1;
165 let res = M::binary_operation(unsafe { self.data.get_unchecked(r) }, &sm);
166 if f(&res) {
167 sm = res;
168 r -= 1;
169 }
170 }
171 return r + 1 - self.size;
172 }
173 sm = M::binary_operation(unsafe { self.data.get_unchecked(r) }, &sm);
174 let r = r as isize;
177 if (r & -r) == r {
178 break;
179 }
180 }
181
182 0
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189 #[test]
190 fn test_practice2_sample() {
191 let a = vec![1, 2, 3, 2, 1];
192 let cxy = vec![(2, 1, 5), (3, 2, 3), (1, 3, 1), (2, 2, 4), (3, 1, 3)];
193
194 let mut st = SegmentTree::<Max>::from(a);
195 let mut ans = vec![];
196 for (c, x, y) in cxy {
197 if c == 1 {
198 st.set(x as usize - 1, y);
199 } else if c == 2 {
200 ans.push(st.query(x as usize - 1, y as usize));
201 } else {
202 ans.push(st.max_right(x as usize - 1, |&v| y > v) as i64 + 1);
203 }
204 }
205
206 assert_eq!(vec![3, 3, 2, 6], ans);
207 }
208}