m1une's library

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

View on GitHub

:heavy_check_mark: Longest True Monoid
(monoid/longest_true.hpp)

Overview

A monoid for finding the maximum length of a contiguous subarray where all elements satisfy a specific condition (e.g., all elements are true or equal to a target value).

Initialization

Convert your target elements into booleans and use the make method to initialize the leaf nodes.

Example

#include "ds/segtree/segtree.hpp"
#include "monoid/longest_true.hpp"
#include <iostream>
#include <vector>

using LTM = m1une::monoid::LongestTrue;

int main() {
    std::vector<long long> A = {1, 3, 3, 4, 3, 3, 3, 1};
    int N = A.size();
    long long target = 3;

    std::vector<LTM::value_type> init_data(N);
    for (int i = 0; i < N; ++i) {
        // Only set to true if the element matches the target
        init_data[i] = LTM::make(A[i] == target);
    }

    m1une::ds::Segtree<LTM> seg(init_data);

    auto res = seg.prod(0, N);
    std::cout << "Max Length of " << target << "s: " << res.max_len << "\n"; // Output: 3

    return 0;
}

Interface and Complexity

This is a stateless algebra tag. Generic data structures use its public value_type, id(), and op(a, b) members. If the type also provides helpers such as make(...) or inv(x), they are described above or in the documented properties.

Each static operation runs in the cost of the underlying operation shown in the properties. Scalar monoids are $O(1)$; monoids whose value_type stores several items, permutations, or matrices scale with that stored size.

Required by

Verified with

Code

#ifndef M1UNE_MONOID_LONGEST_TRUE_HPP
#define M1UNE_MONOID_LONGEST_TRUE_HPP 1

#include <algorithm>

namespace m1une {
namespace monoid {

struct LongestTrueNode {
    int len;
    int max_len;
    int l_len;
    int r_len;
};

// Monoid for finding the maximum length of a contiguous subarray
// where all elements satisfy a certain condition (i.e., are "true").
struct LongestTrue {
    using value_type = LongestTrueNode;
    static constexpr bool commutative = false;

    // The identity element represents an empty array.
    static constexpr value_type id() {
        return {0, 0, 0, 0};
    }

    // Merges two segments.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.len == 0) return b;
        if (b.len == 0) return a;

        value_type res;
        res.len = a.len + b.len;
        res.max_len = std::max({a.max_len, b.max_len, a.r_len + b.l_len});

        res.l_len = a.l_len;
        if (a.len == a.l_len) res.l_len += b.l_len;

        res.r_len = b.r_len;
        if (b.len == b.r_len) res.r_len += a.r_len;

        return res;
    }

    // Helper to securely create a leaf node from a boolean condition.
    static constexpr value_type make(bool val) {
        return {1, val ? 1 : 0, val ? 1 : 0, val ? 1 : 0};
    }
};

}  // namespace monoid
}  // namespace m1une

#endif  // M1UNE_MONOID_LONGEST_TRUE_HPP
#line 1 "monoid/longest_true.hpp"



#include <algorithm>

namespace m1une {
namespace monoid {

struct LongestTrueNode {
    int len;
    int max_len;
    int l_len;
    int r_len;
};

// Monoid for finding the maximum length of a contiguous subarray
// where all elements satisfy a certain condition (i.e., are "true").
struct LongestTrue {
    using value_type = LongestTrueNode;
    static constexpr bool commutative = false;

    // The identity element represents an empty array.
    static constexpr value_type id() {
        return {0, 0, 0, 0};
    }

    // Merges two segments.
    static constexpr value_type op(const value_type& a, const value_type& b) {
        if (a.len == 0) return b;
        if (b.len == 0) return a;

        value_type res;
        res.len = a.len + b.len;
        res.max_len = std::max({a.max_len, b.max_len, a.r_len + b.l_len});

        res.l_len = a.l_len;
        if (a.len == a.l_len) res.l_len += b.l_len;

        res.r_len = b.r_len;
        if (b.len == b.r_len) res.r_len += a.r_len;

        return res;
    }

    // Helper to securely create a leaf node from a boolean condition.
    static constexpr value_type make(bool val) {
        return {1, val ? 1 : 0, val ? 1 : 0, val ? 1 : 0};
    }
};

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