Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 16897e5

Browse files
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

Lines changed: 29 additions & 1 deletion
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

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

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)

AltStyle によって変換されたページ (->オリジナル) /