cp-documentation

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

View the Project on GitHub zawa-tin/cp-documentation

:heavy_check_mark: Test/AOJ/DPL_3_C.test.cpp

Depends on

Code

#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/7/DPL/3/DPL_3_C"

#include "../../Src/Template/IOSetting.hpp"
#include "../../Src/Sequence/CartesianTree.hpp"

#include <algorithm>
#include <iostream>
#include <vector>

using namespace zawa;

int main() {
    SetFastIO();
    int N;
    std::cin >> N;
    std::vector<int> H(N);
    for (auto& h : H) std::cin >> h;
    using Tree = CartesianTree<int>;
    Tree T{H, [](int l, int r) { return l < r; }};
    long long ans{};
    std::vector<int> size(N);
    T.treeDP([&](const Tree::Node& node) {
            auto v{node.idx};
            size[v] = 1;
            if (node.left != Tree::Invalid) size[v] += size[node.left];
            if (node.right != Tree::Invalid) size[v] += size[node.right];
            ans = std::max(ans, (long long)size[v] * node.value);
        });
    std::cout << ans << '\n';
}
#line 1 "Test/AOJ/DPL_3_C.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/7/DPL/3/DPL_3_C"

#line 2 "Src/Template/IOSetting.hpp"

#line 2 "Src/Template/TypeAlias.hpp"

#include <cstdint>
#include <cstddef>

namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa
#line 4 "Src/Template/IOSetting.hpp"

#include <iostream>
#include <iomanip>

namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa
#line 2 "Src/Sequence/CartesianTree.hpp"

#line 4 "Src/Sequence/CartesianTree.hpp"

#include <concepts>
#include <cassert>
#include <type_traits>
#include <vector>

namespace zawa {

template <class T>
class CartesianTree {
public:

    static constexpr usize Invalid{static_cast<usize>(-1)};

    struct Node {
        usize left{Invalid}, right{Invalid}, par{Invalid}, idx{Invalid};
        T value{};
        std::vector<usize> childs() const noexcept {
            std::vector<usize> res;
            res.reserve(2);
            if (left != Invalid) res.push_back(left);
            if (right != Invalid) res.push_back(right);
            return res;
        }
        usize countChilds() const noexcept {
            return (left != Invalid) + (right != Invalid);
        }
    };

    CartesianTree() = default;

    template <class F>
    requires std::strict_weak_order<F, T, T>
    CartesianTree(const std::vector<T>& A, F comp) 
        : m_size{A.size()}, m_nodes(A.size()) {

        std::vector<usize> stack(A.size());
        usize top{};
        for (usize i{} ; i < size() ; i++) {
            if (top and comp(A[i], A[stack[top - 1]])) {
                while (top and comp(A[i], A[stack[top - 1]])) top--;
                m_nodes[i].left = stack[top];
                m_nodes[stack[top]].par = i;
            }
            if (top) {
                m_nodes[i].par = stack[top - 1];
                m_nodes[stack[top - 1]].right = i;
            }
            else {
                m_root = i;
            }
            m_nodes[i].value = A[i];
            m_nodes[i].idx = i;
            stack[top++] = i;
        }
    }

    inline usize size() const noexcept {
        return m_size;
    }

    inline usize root() const noexcept {
        return m_root;
    }

    inline T value(usize i) const noexcept {
        assert(i < size());
        return m_nodes[i].value;
    }

    inline usize parent(usize i) const noexcept {
        assert(i < size());
        return m_nodes[i].par;
    }

    inline usize left(usize i) const noexcept {
        assert(i < size());
        return m_nodes[i].left;
    }

    inline usize right(usize i) const noexcept {
        assert(i < size());
        return m_nodes[i].right;
    }

    template <class F>
    void treeDP(F func) {
        static_assert(std::is_invocable_v<F, const Node&>, "F must be invocable f(const Node&)");
        dfs(m_root, func);
    }

private:

    template <class F>
    void dfs(usize v, F func) {
        if (m_nodes[v].left != Invalid) dfs(m_nodes[v].left, func);
        if (m_nodes[v].right != Invalid) dfs(m_nodes[v].right, func);
        func(m_nodes[v]);
    }

    usize m_size{}, m_root{Invalid};
    std::vector<Node> m_nodes;
};

} // namespace zawa
#line 5 "Test/AOJ/DPL_3_C.test.cpp"

#include <algorithm>
#line 9 "Test/AOJ/DPL_3_C.test.cpp"

using namespace zawa;

int main() {
    SetFastIO();
    int N;
    std::cin >> N;
    std::vector<int> H(N);
    for (auto& h : H) std::cin >> h;
    using Tree = CartesianTree<int>;
    Tree T{H, [](int l, int r) { return l < r; }};
    long long ans{};
    std::vector<int> size(N);
    T.treeDP([&](const Tree::Node& node) {
            auto v{node.idx};
            size[v] = 1;
            if (node.left != Tree::Invalid) size[v] += size[node.left];
            if (node.right != Tree::Invalid) size[v] += size[node.right];
            ans = std::max(ans, (long long)size[v] * node.value);
        });
    std::cout << ans << '\n';
}
Back to top page