diff options
author | Xiaoxu Guo <shimo11370@proton.me> | 2024-06-07 15:27:55 +0800 |
---|---|---|
committer | Xiaoxu Guo <shimo11370@proton.me> | 2024-06-07 15:27:55 +0800 |
commit | 9d1007cbbe280b0dc52e77db1843a0d4d60c5cd2 (patch) | |
tree | de84432dc4711f284cc7154f047280add51bf390 | |
parent | 8f7ef6bae03fca6698d9cd2eb330f01a6cc893b7 (diff) | |
download | shoka-9d1007cbbe280b0dc52e77db1843a0d4d60c5cd2.tar.gz shoka-9d1007cbbe280b0dc52e77db1843a0d4d60c5cd2.zip |
added
-rw-r--r-- | eulerian_tour.h | 25 | ||||
-rw-r--r-- | segment_cover.h | 35 | ||||
-rw-r--r-- | types/graph/adjacent_list_base.h | 22 |
3 files changed, 67 insertions, 15 deletions
diff --git a/eulerian_tour.h b/eulerian_tour.h index 8b60cfe..d755b02 100644 --- a/eulerian_tour.h +++ b/eulerian_tour.h @@ -1,37 +1,32 @@ +#include "types/graph/adjacent_list_base.h" + #include <utility> #include <vector> -class Eulerian { +class Eulerian : public AdjacentListBase<int> { void dfs(int u) { while (~head[u]) { int i = head[u]; head[u] = next[head[u]]; if (!used[i >> 1]) { used[i >> 1] = true; - int v = (i & 1) ? edges[i >> 1].first : edges[i >> 1].second; - dfs(v); + dfs(edges[i]); } } tour.push_back(u); } - int n, m; - std::vector<int> head, next; + int n; std::vector<bool> used; - const std::vector<std::pair<int, int>> &edges; public: explicit Eulerian(int n_, int s, const std::vector<std::pair<int, int>> &edges_) - : n{n_}, m(edges_.size()), head(n, -1), next(m << 1), used(m), - edges{edges_} { - for (int i = 0; i < m << 1; ++i) { - auto [u, v] = edges[i >> 1]; - if (i & 1) { - std::swap(u, v); - } - next[i] = head[u]; - head[u] = i; + : AdjacentListBase<int>{n_, static_cast<int>(edges_.size()) << 1}, n{n_}, + used(edges_.size() << 1) { + for (auto [a, b] : edges_) { + add(a, b); + add(b, a); } dfs(s); } diff --git a/segment_cover.h b/segment_cover.h new file mode 100644 index 0000000..9b93a45 --- /dev/null +++ b/segment_cover.h @@ -0,0 +1,35 @@ +#include <concepts> +#include <functional> +#include <limits> +#include <map> + +template <typename T, std::integral K = int> class SegmentCover { + void cut(K k) { + auto it = std::prev(segs.upper_bound(k)); + if (it->first < k) { + segs[k] = it->second; + } + } + +public: + explicit SegmentCover(T v) { + segs[std::numeric_limits<K>::min()] = segs[std::numeric_limits<K>::max()] = + v; + } + + // set [l, r) to v + void cover(K l, K r, T v, const std::function<void(K, K, T)> &cb) { + cut(l); + cut(r); + auto it = segs.find(l); + while (it->first < r) { + auto iit = std::next(it); + cb(it->first, iit->first, it->second); + segs.erase(it); + it = iit; + } + segs[l] = v; + } + + std::map<K, T> segs; +}; diff --git a/types/graph/adjacent_list_base.h b/types/graph/adjacent_list_base.h new file mode 100644 index 0000000..0c17596 --- /dev/null +++ b/types/graph/adjacent_list_base.h @@ -0,0 +1,22 @@ +#pragma once + +#include <vector> + +template <typename Edge> class AdjacentListBase { +public: + explicit AdjacentListBase(int n_, int m = 0) : n{n_}, head(n, -1) { + next.reserve(m); + edges.reserve(m); + } + + template <typename... Args> void add(int u, Args &&...args) { + int i = next.size(); + next.emplace_back(head[u]); + head[u] = i; + edges.emplace_back(std::forward<Args>(args)...); + } + + int n; + std::vector<int> head, next; + std::vector<Edge> edges; +}; |