Skip to content

Commit 164f17b

Browse files
committed
make segtree to allow more widely functions
1 parent 198f33d commit 164f17b

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

atcoder/lazysegtree.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@
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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,22 @@
66
#include <vector>
77

88
#include "atcoder/internal_bit"
9-
109
namespace atcoder {
1110

11+
#if __cplusplus >= 201703L
12+
13+
template <class S, auto op, auto e> struct segtree {
14+
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
15+
"op must work as S(S, S)");
16+
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
17+
"e must work as S()");
18+
19+
#else
20+
1221
template <class S, S (*op)(S, S), S (*e)()> struct segtree {
22+
23+
#endif
24+
1325
public:
1426
segtree() : segtree(0) {}
1527
explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}

test/unittest/lazysegtree_test.cpp

Lines changed: 30 additions & 0 deletions
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

Lines changed: 25 additions & 0 deletions
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)