m1une's library

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

View on GitHub

:heavy_check_mark: Acted Monoid Concept
(acted_monoid/concept.hpp)

Overview

m1une::acted_monoid::IsActedMonoid is the C++20 concept used by lazy propagation data structures such as LazySegtree.

An acted monoid has three parts:

  1. A value monoid, which combines segment values for queries.
  2. An operator monoid, which combines lazy update operations.
  3. A mapping function, which applies one operator to one value.

For example, in range-add range-sum:

Requirements

The concept requires the type to implement these members:

The concept checks that these expressions are valid and return the exact stated types. It does not require any operation to be constexpr. Associativity, identity laws, and the interaction between mapping and op must be satisfied by the implementation.

Built-in acted monoids also expose two metadata flags:

Generic data structures may use these flags to select faster representations or algorithms. Both members are deliberately optional and are not part of IsActedMonoid, so a contest-local acted monoid may omit them. An omitted flag is treated conservatively by data structures that inspect it.

Commutative Acted Group

m1une::acted_monoid::IsCommutativeActedGroup extends IsActedMonoid with an inverse for the value monoid:

The concept checks only the interface. The value operation should satisfy the commutative group laws, and mapping should still distribute over op.

Complexity

These concepts are compile-time interface checks and have no runtime cost.

Required by

Verified with

Code

#ifndef M1UNE_ACTED_MONOID_CONCEPT_HPP
#define M1UNE_ACTED_MONOID_CONCEPT_HPP 1

#include <concepts>

namespace m1une {
namespace acted_monoid {

// Concept defining the requirements for an Acted Monoid.
template <typename AM>
concept IsActedMonoid = requires(typename AM::value_type a, typename AM::value_type b, typename AM::operator_type f,
                                 typename AM::operator_type g) {
    // 1. Value Monoid
    typename AM::value_type;
    { AM::id() } -> std::same_as<typename AM::value_type>;
    { AM::op(a, b) } -> std::same_as<typename AM::value_type>;

    // 2. Operator Monoid
    typename AM::operator_type;
    { AM::op_id() } -> std::same_as<typename AM::operator_type>;
    { AM::op_comp(f, g) } -> std::same_as<typename AM::operator_type>;  // Composition order: f(g(x))

    // 3. Mapping: Operator x Value -> Value
    { AM::mapping(f, a) } -> std::same_as<typename AM::value_type>;
};

// Concept for acted monoids whose value monoid is a commutative group.
// The value operation must obey commutativity and inverse laws.
template <typename AM>
concept IsCommutativeActedGroup = IsActedMonoid<AM> && requires(typename AM::value_type a) {
    { AM::inv(a) } -> std::same_as<typename AM::value_type>;
};

}  // namespace acted_monoid
}  // namespace m1une

#endif  // M1UNE_ACTED_MONOID_CONCEPT_HPP
#line 1 "acted_monoid/concept.hpp"



#include <concepts>

namespace m1une {
namespace acted_monoid {

// Concept defining the requirements for an Acted Monoid.
template <typename AM>
concept IsActedMonoid = requires(typename AM::value_type a, typename AM::value_type b, typename AM::operator_type f,
                                 typename AM::operator_type g) {
    // 1. Value Monoid
    typename AM::value_type;
    { AM::id() } -> std::same_as<typename AM::value_type>;
    { AM::op(a, b) } -> std::same_as<typename AM::value_type>;

    // 2. Operator Monoid
    typename AM::operator_type;
    { AM::op_id() } -> std::same_as<typename AM::operator_type>;
    { AM::op_comp(f, g) } -> std::same_as<typename AM::operator_type>;  // Composition order: f(g(x))

    // 3. Mapping: Operator x Value -> Value
    { AM::mapping(f, a) } -> std::same_as<typename AM::value_type>;
};

// Concept for acted monoids whose value monoid is a commutative group.
// The value operation must obey commutativity and inverse laws.
template <typename AM>
concept IsCommutativeActedGroup = IsActedMonoid<AM> && requires(typename AM::value_type a) {
    { AM::inv(a) } -> std::same_as<typename AM::value_type>;
};

}  // namespace acted_monoid
}  // namespace m1une
Back to top page