From dd331b50d79393199d857c7c374e92e91ad441ec Mon Sep 17 00:00:00 2001 From: wheson Date: Tue, 26 Jun 2018 19:49:52 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=E4=B8=80=E7=82=B9=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=8C=BA=E9=96=93=E5=8F=96=E5=BE=97=E3=82=BB=E3=82=B0=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E6=9C=A8=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/DataStructure/segment_tree.h | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 lib/DataStructure/segment_tree.h diff --git a/lib/DataStructure/segment_tree.h b/lib/DataStructure/segment_tree.h new file mode 100644 index 0000000..732ac4d --- /dev/null +++ b/lib/DataStructure/segment_tree.h @@ -0,0 +1,61 @@ +#pragma once +#include "template.h" + +// 0-indexed +template +class SegmentTree { + private: + using Func = function; + int n; // 最下段の数 + vector segmentTree; // セグ木本体 + const Func f; // 二項演算 + const Monoid identityElement; // モノイドの単位元 + + public: + SegmentTree(vector vec, const Func f, const Monoid identityElement); + void Update(int idx, Monoid val); + Monoid Query(int a, int b, int k = 0, int l = 0, + int r = -1); // 使う時は区間[a, b)のみ指定すれば良い + Monoid GetNum(int idx); // 元の要素番号から最下層の値を取得 +}; + +template +SegmentTree::SegmentTree(vector vec, const Func f, + const Monoid identityElement) + : f(f), identityElement(identityElement) { + int sz = vec.size(); + n = 1; + while (n < sz) n *= 2; + segmentTree.assign(2 * n - 1, identityElement); + for (int i = 0; i < sz; i++) segmentTree[i + n - 1] = vec[i]; + for (int i = n - 2; i >= 0; i--) + segmentTree[i] = f(segmentTree[2 * i + 1], segmentTree[2 * i + 2]); +} + +template +void SegmentTree::Update(int idx, Monoid val) { + idx += n - 1; + segmentTree[idx] = val; + while (idx > 0) { + idx = (idx - 1) / 2; + segmentTree[idx] = f(segmentTree[2 * idx + 1], segmentTree[2 * idx + 2]); + } +} + +template +Monoid SegmentTree::Query(int a, int b, int k, int l, int r) { + if (r < 0) r = n; + + if (r <= a || b <= l) return identityElement; + + if (a <= l && r <= b) return segmentTree[k]; + + int vl = Query(a, b, 2 * k + 1, l, (l + r) / 2); + int vr = Query(a, b, 2 * k + 2, (l + r) / 2, r); + return f(vl, vr); +} + +template +Monoid SegmentTree::GetNum(int idx) { + return segmentTree[idx + n - 1]; +} From 1195647c778da8b69fae6e5525a9a63bf04920d4 Mon Sep 17 00:00:00 2001 From: wheson Date: Tue, 26 Jun 2018 20:33:56 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=E5=8D=98=E4=B8=80=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=8C=BA=E9=96=93=E5=8F=96=E5=BE=97=E3=82=BB=E3=82=B0=E3=83=A1?= =?UTF-8?q?=E3=83=B3=E3=83=88=E6=9C=A8=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90(RMQ,=20RSQ)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/DataStructure/test_segment_tree.cpp | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/DataStructure/test_segment_tree.cpp diff --git a/test/DataStructure/test_segment_tree.cpp b/test/DataStructure/test_segment_tree.cpp new file mode 100644 index 0000000..492682b --- /dev/null +++ b/test/DataStructure/test_segment_tree.cpp @@ -0,0 +1,28 @@ +#include "gtest/gtest.h" +#include "lib/DataStructure/segment_tree.h" + +// Range Minimum Query +TEST(DataStructureTest, segment_tree_RMQ){ + vector vec(3, (2 << 31) - 1); + SegmentTree segmentTree(vec, [](int a, int b){ return min(a, b); }, (2 << 31) - 1); + + segmentTree.Update(0, 1); + segmentTree.Update(1, 2); + segmentTree.Update(2, 3); + + EXPECT_EQ(segmentTree.Query(0, 2+1), 1); + EXPECT_EQ(segmentTree.Query(1, 2+1), 2); +} + +// Range Sum Query +TEST(DataStructureTest, segment_tree_RSQ){ + vector vec(3, 0); + SegmentTree segmentTree(vec, [](int a, int b){ return a + b; }, 0); + + segmentTree.Update(0, 1); + segmentTree.Update(1, 2); + segmentTree.Update(2, 3); + + EXPECT_EQ(segmentTree.Query(0, 1+1), 3); + EXPECT_EQ(segmentTree.Query(1, 1+1), 2); +} From c4871a3fb6a4f2f2dc494e68affffb8d0ad4ca61 Mon Sep 17 00:00:00 2001 From: wheson Date: Tue, 26 Jun 2018 20:35:24 +0900 Subject: [PATCH 3/8] make format --- test/DataStructure/test_segment_tree.cpp | 33 ++++++++++++------------ 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/test/DataStructure/test_segment_tree.cpp b/test/DataStructure/test_segment_tree.cpp index 492682b..6632676 100644 --- a/test/DataStructure/test_segment_tree.cpp +++ b/test/DataStructure/test_segment_tree.cpp @@ -2,27 +2,28 @@ #include "lib/DataStructure/segment_tree.h" // Range Minimum Query -TEST(DataStructureTest, segment_tree_RMQ){ - vector vec(3, (2 << 31) - 1); - SegmentTree segmentTree(vec, [](int a, int b){ return min(a, b); }, (2 << 31) - 1); +TEST(DataStructureTest, segment_tree_RMQ) { + vector vec(3, (2 << 31) - 1); + SegmentTree segmentTree(vec, [](int a, int b) { return min(a, b); }, + (2 << 31) - 1); - segmentTree.Update(0, 1); - segmentTree.Update(1, 2); - segmentTree.Update(2, 3); + segmentTree.Update(0, 1); + segmentTree.Update(1, 2); + segmentTree.Update(2, 3); - EXPECT_EQ(segmentTree.Query(0, 2+1), 1); - EXPECT_EQ(segmentTree.Query(1, 2+1), 2); + EXPECT_EQ(segmentTree.Query(0, 2 + 1), 1); + EXPECT_EQ(segmentTree.Query(1, 2 + 1), 2); } // Range Sum Query -TEST(DataStructureTest, segment_tree_RSQ){ - vector vec(3, 0); - SegmentTree segmentTree(vec, [](int a, int b){ return a + b; }, 0); +TEST(DataStructureTest, segment_tree_RSQ) { + vector vec(3, 0); + SegmentTree segmentTree(vec, [](int a, int b) { return a + b; }, 0); - segmentTree.Update(0, 1); - segmentTree.Update(1, 2); - segmentTree.Update(2, 3); + segmentTree.Update(0, 1); + segmentTree.Update(1, 2); + segmentTree.Update(2, 3); - EXPECT_EQ(segmentTree.Query(0, 1+1), 3); - EXPECT_EQ(segmentTree.Query(1, 1+1), 2); + EXPECT_EQ(segmentTree.Query(0, 1 + 1), 3); + EXPECT_EQ(segmentTree.Query(1, 1 + 1), 2); } From c8f074f579ddd94a3a9a5c21fd3eebb6d08f3005 Mon Sep 17 00:00:00 2001 From: wheson Date: Tue, 26 Jun 2018 20:45:57 +0900 Subject: [PATCH 4/8] =?UTF-8?q?SegmentTree=E3=81=AB=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=92=E5=85=A5=E3=82=8C=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39e69e2..0412a89 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ # Library List ## データ構造 - [x] UnionFind -- [ ] SegmentTree +- [x] SegmentTree - [ ] BIT(Binary-Indexed-Tree) - [ ] Treap From 798aec08821b4344396b20b4d2f23ba993880fda Mon Sep 17 00:00:00 2001 From: Kita Tomoya Date: Tue, 26 Jun 2018 22:58:57 +0900 Subject: [PATCH 5/8] fix CMakeLists.txt and Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 1485357..654633b 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ build: ${LIBS} make -j 2 test: ${BUILD_DIR} - ${BUILD_DIR}/test/mathTest + ${BUILD_DIR}/test/runTest format: clang-format -i $(FILE) From f18315247339819b054237ce81fb9222d599b89f Mon Sep 17 00:00:00 2001 From: Kita Tomoya Date: Tue, 26 Jun 2018 23:41:57 +0900 Subject: [PATCH 6/8] =?UTF-8?q?CMakeLists.txt=E5=BF=98=E3=82=8C=E3=81=84?= =?UTF-8?q?=E3=81=9F=20:bow:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dc7943d..077a349 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.8) -file(GLOB MATH_TEST_FILES "Math/test_*.cpp") -add_executable(mathTest ${MATH_TEST_FILES}) -target_link_libraries(mathTest ProconMath gtest gtest_main pthread) +file(GLOB TEST_FILES "*/test_*.cpp") +add_executable(runTest ${TEST_FILES}) +target_link_libraries(runTest ProconMath gtest gtest_main pthread) From ed6a67127fdbb8100bf2fb53e362c74debe6c57f Mon Sep 17 00:00:00 2001 From: wheson Date: Tue, 26 Jun 2018 23:53:17 +0900 Subject: [PATCH 7/8] =?UTF-8?q?MAX=E5=80=A4=E3=81=8C=E3=82=AA=E3=83=BC?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=83=95=E3=83=AD=E3=83=BC=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=9F=E3=81=AE=E3=81=A7=E5=B0=8F=E3=81=95=E3=81=8F?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/DataStructure/test_segment_tree.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/DataStructure/test_segment_tree.cpp b/test/DataStructure/test_segment_tree.cpp index 6632676..ddd0b0d 100644 --- a/test/DataStructure/test_segment_tree.cpp +++ b/test/DataStructure/test_segment_tree.cpp @@ -3,9 +3,9 @@ // Range Minimum Query TEST(DataStructureTest, segment_tree_RMQ) { - vector vec(3, (2 << 31) - 1); + vector vec(3, 1e9); SegmentTree segmentTree(vec, [](int a, int b) { return min(a, b); }, - (2 << 31) - 1); + 1e9); segmentTree.Update(0, 1); segmentTree.Update(1, 2); From c00d52e0551ce0d39f3277a3232b431d6e025a55 Mon Sep 17 00:00:00 2001 From: Kita Tomoya Date: Tue, 26 Jun 2018 23:59:31 +0900 Subject: [PATCH 8/8] fix Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 654633b..ae9ef19 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,13 @@ lint: ${LIBS} cpplint ./lib/*/* cpplint ./test/*/* -build: ${LIBS} +build: ${LIBS} ${TESTS} mkdir -p ${BUILD_DIR}; \ cd build; \ cmake ..; \ make -j 2 -test: ${BUILD_DIR} +test: build ${BUILD_DIR}/test/runTest format: