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/LC/cartesian_tree.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/cartesian_tree"

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

#include <functional>
#include <iostream>

using namespace zawa;

int main() {
    SetFastIO(); 
    int N;
    std::cin >> N;
    std::vector<int> A(N);
    for (auto& a : A) std::cin >> a;
    CartesianTree<int> T{A, std::less{}};
    for (int i{} ; i < N ; i++) {
       usize p{T.parent(i)}; 
       std::cout << (p == decltype(T)::Invalid ? (usize)i : p) << (i + 1 == N ? '\n' : ' ');
    }
}
#line 1 "Test/LC/cartesian_tree.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/cartesian_tree"

#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/LC/cartesian_tree.test.cpp"

#include <functional>
#line 8 "Test/LC/cartesian_tree.test.cpp"

using namespace zawa;

int main() {
    SetFastIO(); 
    int N;
    std::cin >> N;
    std::vector<int> A(N);
    for (auto& a : A) std::cin >> a;
    CartesianTree<int> T{A, std::less{}};
    for (int i{} ; i < N ; i++) {
       usize p{T.parent(i)}; 
       std::cout << (p == decltype(T)::Invalid ? (usize)i : p) << (i + 1 == N ? '\n' : ' ');
    }
}
Back to top page