Skip to content

Commit 16897e5

Browse files
authored
Merge pull request #160 from yosupo06/patch/segtree
make segtree to allow more broad function types
2 parents 198f33d + 5c1dbb4 commit 16897e5

File tree

4 files changed

+98
-1
lines changed

4 files changed

+98
-1
lines changed

atcoder/lazysegtree.hpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,38 @@
33

44
#include <algorithm>
55
#include <cassert>
6-
#include <iostream>
6+
#include <functional>
77
#include <vector>
88

99
#include "atcoder/internal_bit"
1010

1111
namespace atcoder {
1212

13+
#if __cplusplus >= 201703L
14+
15+
template <class S,
16+
auto op,
17+
auto e,
18+
class F,
19+
auto mapping,
20+
auto composition,
21+
auto id>
22+
struct lazy_segtree {
23+
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
24+
"op must work as S(S, S)");
25+
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
26+
"e must work as S()");
27+
static_assert(
28+
std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
29+
"mapping must work as F(F, S)");
30+
static_assert(
31+
std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
32+
"compostiion must work as F(F, F)");
33+
static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
34+
"id must work as F()");
35+
36+
#else
37+
1338
template <class S,
1439
S (*op)(S, S),
1540
S (*e)(),
@@ -18,6 +43,9 @@ template <class S,
1843
F (*composition)(F, F),
1944
F (*id)()>
2045
struct lazy_segtree {
46+
47+
#endif
48+
2149
public:
2250
lazy_segtree() : lazy_segtree(0) {}
2351
explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}

atcoder/segtree.hpp

+14
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,27 @@
33

44
#include <algorithm>
55
#include <cassert>
6+
#include <functional>
67
#include <vector>
78

89
#include "atcoder/internal_bit"
910

1011
namespace atcoder {
1112

13+
#if __cplusplus >= 201703L
14+
15+
template <class S, auto op, auto e> struct segtree {
16+
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
17+
"op must work as S(S, S)");
18+
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
19+
"e must work as S()");
20+
21+
#else
22+
1223
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
24+
25+
#endif
26+
1327
public:
1428
segtree() : segtree(0) {}
1529
explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}

test/unittest/lazysegtree_test.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,33 @@ TEST(LazySegtreeTest, Usage) {
8585
ASSERT_EQ(-5, seg.prod(2, 3));
8686
ASSERT_EQ(0, seg.prod(2, 4));
8787
}
88+
89+
#if __cplusplus >= 201703L
90+
91+
int op_const(const int& a, const int& b) { return std::max(a, b); }
92+
93+
struct const_starry {
94+
static int op_ss(const int& a, const int& b) { return std::max(a, b); }
95+
static int op_ts(const int& a, const int& b) { return a + b; }
96+
static int op_tt(const int& a, const int& b) { return a + b; }
97+
};
98+
99+
TEST(SegtreeTest, ConstFunc) {
100+
lazy_segtree<int, const_starry::op_ss, starry::e_s, int,
101+
const_starry::op_ts, const_starry::op_tt, starry::e_t>
102+
seg(10);
103+
}
104+
105+
#endif
106+
107+
#if __cplusplus >= 202002L
108+
109+
TEST(LazySegtreeTest, LambdaFunc) {
110+
lazy_segtree<int, [](int a, int b) { return std::max(a, b); },
111+
[]() { return -1'000'000'000; }, int,
112+
[](int a, int b) { return a + b; },
113+
[](int a, int b) { return a + b; }, []() { return 0; }>
114+
seg(10);
115+
}
116+
117+
#endif

test/unittest/segtree_test.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,28 @@ TEST(SegtreeTest, Assign) {
144144
seg seg0;
145145
seg0 = seg(10);
146146
}
147+
148+
#if __cplusplus >= 201703L
149+
150+
std::string op_const(const std::string& a, const std::string& b) {
151+
assert(a == "$" || b == "$" || a <= b);
152+
if (a == "$") return b;
153+
if (b == "$") return a;
154+
return a + b;
155+
}
156+
157+
TEST(SegtreeTest, ConstFunc) {
158+
segtree<std::string, op_const, e> s1(10);
159+
}
160+
161+
#endif
162+
163+
#if __cplusplus >= 202002L
164+
165+
TEST(SegtreeTest, LambdaFunc) {
166+
segtree<std::string, [](std::string a, std::string b) {
167+
return a + b;
168+
}, []() { return ""; }> s1(10);
169+
}
170+
171+
#endif

0 commit comments

Comments
 (0)