This documentation is automatically generated by online-judge-tools/verification-helper
#include "Src/Algebra/Monoid/SameMonoid.hpp"
しばしば「指定された集合 $S$ に属する要素が全て同じ値か $o(|S|)$ で判定せよ」といった問題が要求されることがある。
こういったクエリをデータ構造に載せたい時用。
std::optional<T>
の運用については std::optional cpprefjp 等も参考にすること。
(1) SameMonoidData<T>() = default;
(2) SameMonoidData<T>(const T& element)
(3) SameMonoidData<T>(const std::optional<T>& element, bool same)
(1) 空集合の時
(2) 単一要素element
からなる集合の時
(3) ユーザー側からの使用は特に想定していない。protectedとかにすればよかったかも。
bool SameMonoidData<T>::empty() const noexcept
持っている集合が空集合の時true
bool SameMonoidData<T>::same() const noexcept
持っている集合が空または単一要素からなる多重集合の時true
std::optional<T> SameMonoidData<T>::element() const noexcept
集合の代表元を返す。集合が空だったり単一要素から構成されていない場合はstd::nullopt
が返る。
T SameMonoidData<T>::value() const noexcept
集合の代表元を返す。集合が空だったり単一要素から構成されていない場合は実行時エラーになる。
#pragma once
#include <optional>
namespace zawa {
template <class T>
class SameMonoidData {
private:
std::optional<T> element_{};
bool same_{true};
public:
static std::optional<T> merge(const std::optional<T>& l, const std::optional<T>& r) noexcept {
if (l and r) return (l.value() == r.value() ? l : std::nullopt);
if (l) return l;
if (r) return r;
return std::nullopt;
}
SameMonoidData() = default;
SameMonoidData(const T& element)
: element_{element}, same_{true} {}
SameMonoidData(const std::optional<T>& element, bool same)
: element_{element}, same_{same} {}
bool empty() const noexcept {
return same_ and !element_.has_value();
}
bool same() const noexcept {
return same_;
}
std::optional<T> element() const noexcept {
return element_;
}
T value() const noexcept {
return element_.value();
}
};
template <class T>
struct SameMonoid {
public:
using Element = SameMonoidData<T>;
static Element identity() noexcept {
return Element{};
}
static Element operation(const Element& l, const Element& r) {
if (l.empty() and r.empty()) return identity();
if (l.empty()) return r;
if (r.empty()) return l;
std::optional<T> element{Element::merge(l.element(), r.element())};
return Element{element, l.same() and r.same() and element.has_value()};
}
};
} // namespace zawa
#line 2 "Src/Algebra/Monoid/SameMonoid.hpp"
#include <optional>
namespace zawa {
template <class T>
class SameMonoidData {
private:
std::optional<T> element_{};
bool same_{true};
public:
static std::optional<T> merge(const std::optional<T>& l, const std::optional<T>& r) noexcept {
if (l and r) return (l.value() == r.value() ? l : std::nullopt);
if (l) return l;
if (r) return r;
return std::nullopt;
}
SameMonoidData() = default;
SameMonoidData(const T& element)
: element_{element}, same_{true} {}
SameMonoidData(const std::optional<T>& element, bool same)
: element_{element}, same_{same} {}
bool empty() const noexcept {
return same_ and !element_.has_value();
}
bool same() const noexcept {
return same_;
}
std::optional<T> element() const noexcept {
return element_;
}
T value() const noexcept {
return element_.value();
}
};
template <class T>
struct SameMonoid {
public:
using Element = SameMonoidData<T>;
static Element identity() noexcept {
return Element{};
}
static Element operation(const Element& l, const Element& r) {
if (l.empty() and r.empty()) return identity();
if (l.empty()) return r;
if (r.empty()) return l;
std::optional<T> element{Element::merge(l.element(), r.element())};
return Element{element, l.same() and r.same() and element.has_value()};
}
};
} // namespace zawa