m1une's library

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: monoid/prim_monoids.hpp

Depends on

Code

#ifndef M1UNE_PRIM_MONOIDS_HPP
#define M1UNE_PRIM_MONOIDS_HPP 1

#include "monoid.hpp"
#include "monoids/add_monoid.hpp"
#include "monoids/mul_monoid.hpp"
#include "monoids/min_monoid.hpp"
#include "monoids/max_monoid.hpp"
#include "monoids/minmax_monoid.hpp"
#include "monoids/and_monoid.hpp"
#include "monoids/or_monoid.hpp"
#include "monoids/xor_monoid.hpp"
#include "monoids/affine_monoid.hpp"
#include "monoids/update_monoid.hpp"

#endif  // M1UNE_PRIM_MONOIDS_HPP
#line 1 "monoid/prim_monoids.hpp"



#line 1 "monoid/monoid.hpp"



#include <concepts>
#include <functional>
#include <type_traits>

namespace m1une {

template <typename T, auto operation, auto identity, bool commutative>
struct monoid {
    static_assert(std::is_invocable_r_v<T, decltype(operation), T, T>, "operation must work as T(T, T)");
    static_assert(std::is_invocable_r_v<T, decltype(identity)>, "identity must work as T()");

    using value_type = T;
    static constexpr auto op = operation;
    static constexpr auto id = identity;
    static constexpr bool is_commutative = commutative;
};

template <typename T>
concept Monoid = requires(typename T::value_type v) {
    typename T::value_type;
    { T::op(v, v) } -> std::same_as<typename T::value_type>;
    { T::id() } -> std::same_as<typename T::value_type>;
    { T::is_commutative } -> std::convertible_to<bool>;
};

}  // namespace m1une


#line 1 "monoid/monoids/add_monoid.hpp"



#line 5 "monoid/monoids/add_monoid.hpp"

namespace m1une {

template <typename T>
using add_monoid = monoid<T, [](T a, T b) { return a + b; }, []() { return T(0); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/mul_monoid.hpp"



#line 5 "monoid/monoids/mul_monoid.hpp"

namespace m1une {

template <typename T>
using mul_monoid = monoid<T, [](T a, T b) { return a * b; }, []() { return T(1); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/min_monoid.hpp"



#include <algorithm>
#include <limits>

#line 8 "monoid/monoids/min_monoid.hpp"

namespace m1une {

template <typename T>
using min_monoid =
    monoid<T, [](T a, T b) { return std::min(a, b); }, []() { return std::numeric_limits<T>::max(); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/max_monoid.hpp"



#line 6 "monoid/monoids/max_monoid.hpp"

#line 8 "monoid/monoids/max_monoid.hpp"

namespace m1une {

template <typename T>
using max_monoid =
    monoid<T, [](T a, T b) { return std::max(a, b); }, []() { return std::numeric_limits<T>::min(); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/minmax_monoid.hpp"



#line 6 "monoid/monoids/minmax_monoid.hpp"
#include <utility>

#line 9 "monoid/monoids/minmax_monoid.hpp"

namespace m1une {

// Monoid for storing both a minimum and maximum value.
// The operation combines two pairs by taking the component-wise min and max.
template <typename T>
using minmax_monoid =
    monoid<std::pair<T, T>,
           [](std::pair<T, T> a, std::pair<T, T> b) {
               return std::pair<T, T>(std::min(a.first, b.first), std::max(a.second, b.second));
           },
           []() { return std::pair<T, T>(std::numeric_limits<T>::max(), std::numeric_limits<T>::lowest()); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/and_monoid.hpp"



#line 5 "monoid/monoids/and_monoid.hpp"

namespace m1une {

template <typename T>
using and_monoid = monoid<T, [](T a, T b) { return a & b; }, []() { return ~T(0); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/or_monoid.hpp"



#line 5 "monoid/monoids/or_monoid.hpp"

namespace m1une {

template <typename T>
using or_monoid = monoid<T, [](T a, T b) { return a | b; }, []() { return T(0); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/xor_monoid.hpp"



#line 5 "monoid/monoids/xor_monoid.hpp"

namespace m1une {

template <typename T>
using xor_monoid = monoid<T, [](T a, T b) { return a ^ b; }, []() { return T(0); }, true>;

}  // namespace m1une


#line 1 "monoid/monoids/affine_monoid.hpp"



#line 5 "monoid/monoids/affine_monoid.hpp"

#line 7 "monoid/monoids/affine_monoid.hpp"

namespace m1une {

// Affine transformation f(x) = ax + b is represented as (a, b)
// perform f first, then g
// op(f, g)(x) = g(f(x))
template <typename T>
using affine_monoid = monoid<std::pair<T, T>,
                             [](std::pair<T, T> f, std::pair<T, T> g) {
                                 return std::pair<T, T>(f.first * g.first, f.second * g.first + g.second);
                             },
                             []() { return std::pair<T, T>(1, 0); }, false>;

}  // namespace m1une


#line 1 "monoid/monoids/update_monoid.hpp"



#line 5 "monoid/monoids/update_monoid.hpp"

namespace m1une {

template <typename T, T identity>
using update_monoid = monoid<T,
                             [](T a, T b) {
                                 if (b == identity) return a;
                                 return b;
                             },
                             []() { return identity; }, false>;

}  // namespace m1une


#line 15 "monoid/prim_monoids.hpp"
Back to top page