maomao90's Library
A C++20 library for competitive programming.
Loading...
Searching...
No Matches
segtree.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <vector>
5
7
8// Modified from https://judge.yosupo.jp/submission/268423
9
10namespace maomao90 {
11using namespace std;
12
13// 0-indexed
14// left_monoid.merge(right_monoid)
15template <Monoid T> struct SegTree {
16 SegTree() : SegTree(0) {}
17 explicit SegTree(int n) : SegTree(vector<T>(n, T::id())) {}
18 explicit SegTree(const vector<T> &a) : n(int(a.size())) {
19 size = 1;
20 log = 0;
21 while (size < n) {
22 size <<= 1;
23 log++;
24 }
25 v = vector<T>(2 * size, T::id());
26 for (int i = 0; i < n; i++) {
27 v[size + i] = a[i];
28 }
29 for (int i = size - 1; i >= 1; i--) {
30 update(i);
31 }
32 }
33
34 void set(int p, T x) {
35 assert(0 <= p && p < n);
36 p += size;
37 v[p] = x;
38 for (int i = 1; i <= log; i++) {
39 update(p >> i);
40 }
41 }
42
43 T get(int p) {
44 assert(0 <= p && p < n);
45 return v[p + size];
46 }
47
48 // query [l, r) inclusive of left endpoint, exclusive of right endpoint
49 T query(int l, int r) {
50 if (l >= r) {
51 return T::id();
52 }
53 assert(0 <= l && r <= n);
54
55 l += size;
56 r += size;
57
58 T sml = T::id(), smr = T::id();
59 int i = 1;
60 for (; l < r; i++, l >>= 1, r >>= 1) {
61 if (l & 1) {
62 sml = sml.merge(v[l++]);
63 }
64 if (r & 1) {
65 smr = v[--r].merge(smr);
66 }
67 }
68 return sml.merge(smr);
69 }
70
71 T all_query() { return v[1]; }
72
73 template <bool (*pred)(T)> int max_right(int l) {
74 return max_right(l, [](T x) { return pred(x); });
75 }
76
77 // returns largest x such that pred(query(l, x)) is true (note that right
78 // endpoint `x` is exclusive)
79 template <class P> int max_right(int l, P pred) {
80 assert(0 <= l && l <= n);
81 assert(pred(T::id()));
82 if (l == n) {
83 return n;
84 }
85 l += size;
86 T sm = T::id();
87 do {
88 while (l % 2 == 0) {
89 l >>= 1;
90 }
91 if (!pred(sm.merge(v[l]))) {
92 while (l < size) {
93 l = (2 * l);
94 if (pred(sm.merge(v[l]))) {
95 sm = sm.merge(v[l]);
96 l++;
97 }
98 }
99 return l - size;
100 }
101 sm = sm.merge(v[l]);
102 l++;
103 } while ((l & -l) != l);
104 return n;
105 }
106
107 template <bool (*pred)(T)> int min_left(int r) {
108 return min_left(r, [](T x) { return pred(x); });
109 }
110 // returns smallest x such that pred(query(x, r)) is true (note that right
111 // endpoint `r` is exlusive)
112 template <class P> int min_left(int r, P pred) {
113 assert(-1 <= r && r <= n);
114 if (r == 0) {
115 return 0;
116 }
117 assert(pred(T::id()));
118 r += size;
119 T sm = T::id();
120 do {
121 r--;
122 while (r > 1 && (r % 2)) {
123 r >>= 1;
124 }
125 if (!pred(v[r].merge(sm))) {
126 while (r < size) {
127 r = (2 * r + 1);
128 if (pred(v[r].merge(sm))) {
129 sm = v[r].merge(sm);
130 r--;
131 }
132 }
133 return r + 1 - size;
134 }
135 sm = v[r].merge(sm);
136 } while ((r & -r) != r);
137 return 0;
138 }
139
140private:
141 int n, size, log;
142 vector<T> v;
143
144 void update(int k) { v[k] = v[2 * k].merge(v[2 * k + 1]); }
145};
146} // namespace maomao90
Definition hashmap.hpp:8
SegTree()
Definition segtree.hpp:16
int max_right(int l, P pred)
Definition segtree.hpp:79
void set(int p, T x)
Definition segtree.hpp:34
int min_left(int r)
Definition segtree.hpp:107
int min_left(int r, P pred)
Definition segtree.hpp:112
T all_query()
Definition segtree.hpp:71
SegTree(const vector< T > &a)
Definition segtree.hpp:18
T get(int p)
Definition segtree.hpp:43
T query(int l, int r)
Definition segtree.hpp:49
int max_right(int l)
Definition segtree.hpp:73
SegTree(int n)
Definition segtree.hpp:17