@@ -3,16 +3,41 @@ const math = std.math;
33const Allocator = std .mem .Allocator ;
44const assert = std .debug .assert ;
55
6+ /// Segment Tree
7+ /// Reference: https://en.wikipedia.org/wiki/Segment_tree
8+ ///
9+ /// This is a wrapper around a tree of element type T, update operation op, and identity e.
10+ /// The following should be defined.
11+ ///
12+ /// - The type `S` of the monoid
13+ /// - The binary operation `op: fn (S, S) S`
14+ /// - The identity element `e: fn () S`
15+ ///
16+ /// Initialize with `init`.
617pub fn Segtree (comptime S : type , comptime op : fn (S , S ) S , comptime e : fn () S ) type {
718 return struct {
819 const Self = @This ();
920
21+ /// original array length
1022 n : usize ,
23+ /// internal tree size (power of two ≥ n)
1124 size : usize ,
25+ /// tree height used by `set`
1226 log : usize ,
27+ /// backing array: [size...2*size)
1328 d : []S ,
1429 allocator : Allocator ,
1530
31+ /// Creates an empty tree of length `n`, initialised with the identity.
32+ /// Deinitialize with `deinit`.
33+ ///
34+ /// # Constraints
35+ ///
36+ /// - $0 \leq n < 10^8$
37+ ///
38+ /// # Complexity
39+ ///
40+ /// - $O(n)$
1641 pub fn init (allocator : Allocator , n : usize ) ! Self {
1742 const size = try math .ceilPowerOfTwo (usize , n );
1843 const log = @ctz (size );
@@ -26,6 +51,17 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
2651 @memset (self .d , e ());
2752 return self ;
2853 }
54+
55+ /// Build a tree from an existing slice.
56+ /// Deinitialize with `deinit`.
57+ ///
58+ /// # Constraints
59+ ///
60+ /// - $0 \leq `v.len` < 10^8$
61+ ///
62+ /// # Complexity
63+ ///
64+ /// - $O(n)$ (where $n$ is the length of `v`)
2965 pub fn initFromSlice (allocator : Allocator , v : []const S ) ! Self {
3066 const n = v .len ;
3167 const size = try math .ceilPowerOfTwo (usize , n );
@@ -47,9 +83,25 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
4783 }
4884 return self ;
4985 }
86+
87+ /// Release all allocated memory.
5088 pub fn deinit (self : * Self ) void {
5189 self .allocator .free (self .d );
5290 }
91+
92+ /// Assigns `x` to `a[pos]`
93+ ///
94+ /// # Constraints
95+ ///
96+ /// - $0 \leq p < n$
97+ ///
98+ /// # Panics
99+ ///
100+ /// Panics if the above constraints are not satisfied.
101+ ///
102+ /// # Complexity
103+ ///
104+ /// - $O(\log n)$
53105 pub fn set (self : * Self , pos : usize , x : S ) void {
54106 assert (pos < self .n );
55107 const p = pos + self .size ;
@@ -58,13 +110,48 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
58110 self .update (p >> @intCast (i ));
59111 }
60112 }
113+
114+ /// Returns `a[p]`
115+ ///
116+ /// # Constraints
117+ ///
118+ /// - $0 \leq p < n$
119+ ///
120+ /// # Panics
121+ ///
122+ /// Panics if the above constraints are not satisfied.
123+ ///
124+ /// # Complexity
125+ ///
126+ /// - $O(1)$
61127 pub fn get (self : * Self , p : usize ) S {
62128 assert (p < self .n );
63129 return self .d [p + self .size ];
64130 }
131+
132+ /// Returns the underlying leaf slice `[0, n)`.
133+ ///
134+ /// # Complexity
135+ ///
136+ /// - $O(1)$
65137 pub fn getSlice (self : * Self ) []S {
66138 return self .d [self .size .. self .size + self .n ];
67139 }
140+
141+ /// Returns op(a[l], ..., a[r - 1]), assuming the properties of the monoid.
142+ /// Returns e() if l = r.
143+ ///
144+ /// # Constraints
145+ ///
146+ /// - $0 \leq l \leq r < n$
147+ ///
148+ /// # Panics
149+ ///
150+ /// Panics if the above constraints are not satisfied.
151+ ///
152+ /// # Complexity
153+ ///
154+ /// - $O(\log n)$
68155 pub fn prod (self : * Self , left : usize , right : usize ) S {
69156 assert (left <= right and right <= self .n );
70157
@@ -90,9 +177,38 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
90177
91178 return op (sml , smr );
92179 }
180+
181+ /// Returns op(a[0], ..., a[n - 1]), assuming the properties of the monoid.
182+ /// Returns e() if n = 0.
183+ ///
184+ /// # Complexity
185+ ///
186+ /// - $O(1)$
93187 pub fn allProd (self : * Self ) S {
94188 return self .d [1 ];
95189 }
190+
191+ /// Applies binary search on the segment tree.
192+ /// Returns an index `r` that satisfies both of the following.
193+ ///
194+ /// - `r = l` or `f(context, op(a[l], a[l + 1], ..., a[r - 1])) = true`
195+ /// - `r = n` or `f(context, op(a[l], a[l + 1], ..., a[r])) = false`
196+ ///
197+ /// If `f` is monotone, this is the maximum `r` that satisfies `f(context, op(a[l], a[l + 1], ..., a[r - 1])) = true`.
198+ ///
199+ /// # Constraints
200+ ///
201+ /// - if `f` is called with the same argument, it returns the same value, i.e., `f/ has no side effect.
202+ /// - `f(context, e()) = true`
203+ /// - $0 \leq l \leq n$
204+ ///
205+ /// # Panics
206+ ///
207+ /// Panics if the above constraints are not satisfied.
208+ ///
209+ /// # Complexity
210+ ///
211+ /// - $O(\log n)$
96212 pub fn maxRight (self : * Self , left : usize , context : anytype , comptime f : fn (@TypeOf (context ), S ) bool ) usize {
97213 assert (left <= self .n );
98214 assert (f (context , e ()));
@@ -126,6 +242,28 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
126242 }
127243 return self .n ;
128244 }
245+
246+ /// Applies binary search on the segment tree.
247+ /// Returns an index `l` that satisfies both of the following.
248+ ///
249+ /// - `l = r` or `f(context, op(a[l], a[l + 1], ..., a[r - 1])) = true`
250+ /// - `l = 0` or `f(context, op(a[l - 1], a[l], ..., a[r - 1])) = false`
251+ ///
252+ /// If `f` is monotone, this is the minimum `l` that satisfies `f(context, op(a[l], a[l + 1], ..., a[r - 1])) = true`.
253+ ///
254+ /// # Constraints
255+ ///
256+ /// - if `f` is called with the same argument, it returns the same value, i.e., `f` has no side effect.
257+ /// - `f(context, e()) = true`
258+ /// - $0 \leq r \leq n$
259+ ///
260+ /// # Panics
261+ ///
262+ /// Panics if the above constraints are not satisfied.
263+ ///
264+ /// # Complexity
265+ ///
266+ /// - $O(\log n)$
129267 pub fn minLeft (self : * Self , right : usize , context : anytype , comptime f : fn (@TypeOf (context ), S ) bool ) usize {
130268 assert (right <= self .n );
131269 assert (f (context , e ()));
@@ -159,12 +297,18 @@ pub fn Segtree(comptime S: type, comptime op: fn (S, S) S, comptime e: fn () S)
159297 }
160298 return 0 ;
161299 }
300+
301+ /// Internal helper function:
302+ /// Recomputes node `k` from its two children.
162303 fn update (self : * Self , k : usize ) void {
163304 self .d [k ] = op (self .d [2 * k ], self .d [2 * k + 1 ]);
164305 }
165306 };
166307}
167308
309+ /// Sugar helper that turns a *namespace* with fields `S`, `op`, and `e`.
310+ ///
311+ /// Initialize with `init`.
168312pub fn SegtreeFromNS (comptime ns : anytype ) type {
169313 return Segtree (
170314 ns .S ,
0 commit comments