From ce8a05f5a3a8e77de81ef453411e8a0794d9d0f4 Mon Sep 17 00:00:00 2001 From: oitl-5ab <61768808+oitl-5ab@users.noreply.github.com> Date: Sun, 13 Sep 2020 10:33:49 +0800 Subject: [PATCH] Updated on Indev-0.1 Indev-0.1 updates: Fixed BIT, Added DSU. --- assets/binary_indexed_tree.hpp | 17 +++++-- assets/disjoint_set_union.hpp | 73 ++++++++++++++++++++++++++++++ disjoint_set_union | 6 +++ tests/Test-binary_indexed_tree.cpp | 24 +++++++--- tests/Test-disjoint_set_union.cpp | 42 +++++++++++++++++ 5 files changed, 152 insertions(+), 10 deletions(-) create mode 100644 assets/disjoint_set_union.hpp create mode 100644 disjoint_set_union create mode 100644 tests/Test-disjoint_set_union.cpp diff --git a/assets/binary_indexed_tree.hpp b/assets/binary_indexed_tree.hpp index 121546a..37e1c15 100644 --- a/assets/binary_indexed_tree.hpp +++ b/assets/binary_indexed_tree.hpp @@ -22,12 +22,13 @@ namespace oitl private: #if __cplusplus >= 201103L - std::array __bit; + std::array __bit; #else - value_type __bit[_N]; + value_type __bit[_N + 1]; #endif operate_type __calc; + value_type __identity; void _Add(const int __ptr, value_type __val) { @@ -43,7 +44,7 @@ namespace oitl value_type _Get(const int __ptr) const { register int __i = __ptr; - value_type __ret; + value_type __ret = __identity; while (__i > 0) { @@ -56,6 +57,16 @@ namespace oitl public: + binary_indexed_tree(value_type _Identity = value_type(0)) : __identity(_Identity) + { + #if __cplusplus >= 201103L + __bit.fill(__identity); + #else + for (register int __i = 0; __i < _N; ++__i) + __bit[__i] = __identity; + #endif + } + void modify(int __ptr, _Val_t __val) { _Add(__ptr + 1, __val); diff --git a/assets/disjoint_set_union.hpp b/assets/disjoint_set_union.hpp new file mode 100644 index 0000000..d361f0a --- /dev/null +++ b/assets/disjoint_set_union.hpp @@ -0,0 +1,73 @@ +#ifndef _OITL_ASSETS_DISJOINT_SET_UNION +#define _OITL_ASSETS_DISJOINT_SET_UNION 1 + +#include + +namespace oitl +{ + class disjoint_set_union + { + private: + + std::vector __dsu; + + int _Find_root(int __id) + { + if (__id != __dsu[__id]) + __dsu[__id] = _Find_root(__dsu[__id]); + + return __dsu[__id]; + } + + public: + + disjoint_set_union(int __siz = 0) + { + __dsu.resize(__siz); + for (register int __i = 0; __i < __siz; ++__i) + __dsu[__i] = __i; + } + + bool empty() const { return __dsu.size() == 0; } + int size() const { return __dsu.size(); } + void reset() { __dsu.clear(); } + + bool same_set(int __ap, int __bp) + { + return _Find_root(__ap) == _Find_root(__bp); + } + + void unite_sets(int __ap, int __bp) + { + if (same_set(__ap, __bp)) + return; + + __dsu[_Find_root(__ap)] = _Find_root(__bp); + } + + int add_element() + { + __dsu.push_back(__dsu.size()); + return __dsu.size() - 1; + } + + void clear() + { + for (register int __i = 0; __i < __dsu.size(); ++__i) + __dsu[__i] = __i; + } + + void resize(int __siz) + { + if (__siz > __dsu.size()) + { + for (register int __i = __dsu.size(); __i < __siz; ++__i) + __dsu.push_back(__i); + } + else + __dsu.resize(__siz); + } + }; +} + +#endif \ No newline at end of file diff --git a/disjoint_set_union b/disjoint_set_union new file mode 100644 index 0000000..f70773e --- /dev/null +++ b/disjoint_set_union @@ -0,0 +1,6 @@ +#ifndef _OITL_DISJOINT_SET_UNION_LIB +#define _OITL_DISJOINT_SET_UNION_LIB 1 + +#include "./assets/disjoint_set_union.hpp" + +#endif \ No newline at end of file diff --git a/tests/Test-binary_indexed_tree.cpp b/tests/Test-binary_indexed_tree.cpp index c3a63de..20d25a7 100644 --- a/tests/Test-binary_indexed_tree.cpp +++ b/tests/Test-binary_indexed_tree.cpp @@ -2,7 +2,7 @@ #include using namespace std; -const int max_n = 1000, max_q = 100; +const int max_n = 1000, max_q = 100000; int bf[max_n]; int main() @@ -11,26 +11,36 @@ int main() uniform_int_distribution ug; int n = max_n, rp; + long long tot = 0; oitl::binary_indexed_tree > bit; for (int i = 0; i < n; i++) { bf[i] = ug(ds); - bit.modify(i, bf[i]); + tot += bf[i]; + + // printf("%lld ", bit.query(i)); + + bit.modify(i, (long long)bf[i]); + + // printf("%lld %lld\n", tot, bit.query(i)); } for (int i = 0; i < max_q; i++) { rp = (ug(ds) % max_n + max_n) % max_n; - int ans = bit.query(rp); + long long ans = bit.query(rp), tmp = 0; for (int j = 0; j <= rp; j++) - ans -= bf[j]; + tmp += bf[j]; - if (ans == 0) - printf("Accepted on test #%d.\n", i); + if (ans == tmp) + { + if (!(i % 100)) + printf("Accepted on test #%d.\n", i); + } else - printf("Unaccepted on test #%d.\n", i); + printf("Unaccepted on test #%d. In range [1, %d], Expected %lld but found %lld.\n", i, rp + 1, tmp, ans); } return 0; diff --git a/tests/Test-disjoint_set_union.cpp b/tests/Test-disjoint_set_union.cpp new file mode 100644 index 0000000..bdbcc4b --- /dev/null +++ b/tests/Test-disjoint_set_union.cpp @@ -0,0 +1,42 @@ +#include "../disjoint_set_union" +#include + +using namespace std; + +const int max_n = 100000, mod = 998244353; +int ans = 0; + +void addans(bool res) +{ + ans = (2 * ans + res) % mod; +} + +int main() +{ + freopen("1.in", "r", stdin); + + oitl::disjoint_set_union dsu; + + int n, m, opt, u, v; + + scanf("%d%d", &n, &m); + for (int i = 0; i < n; i++) + dsu.add_element(); + + while (m--) + { + scanf("%d%d%d", &opt, &u, &v); + + if (opt) + addans(dsu.same_set(u, v)); + else + dsu.unite_sets(u, v); + + if (!(m % 100000)) + printf("%d\n", m); + } + + printf("%d\n", ans); + + return 0; +}