// #pragma once

// #include <iostream>
// #include <ostream>
// #include <sstream>
// #include <stdexcept>
// #include <string>
// #include <type_traits>
// #include "Stack.hpp"

// namespace zt {
//     template<class T>
//     class CartesianTree{
//     public:
//         using valueType = std::remove_cv_t<T>;
//     private:
//         struct Node{
//             valueType val;
//             Node* leftSon{nullptr};
//             Node* rightSon{nullptr};
//         };
//         Stack<Node*> stack;
//         Node* root{nullptr};
//         void _dfs(Node *now,void(*func)(Node* now)){
//             if(now->leftSon!=nullptr){
//                 _dfs(now->leftSon, func);
//             }
//             if(now->rightSon!=nullptr){
//                 _dfs(now->rightSon, func);
//             }
//             func(now);
//         }
//         void _dfs(const Node *const now,void(*func)(Node*const now))const{
//             if(now->leftSon!=nullptr){
//                 _dfs(now->leftSon, func);
//             }
//             if(now->rightSon!=nullptr){
//                 _dfs(now->rightSon, func);
//             }
//             func(now);
//         }
//         void _toString(const Node*const now,std::stringstream&ss)const{
//             if(now->leftSon!=nullptr){
//                 _toString(now->leftSon, ss);
//             }
//             ss<<now->val<<", ";
//             if(now->rightSon!=nullptr){
//                 _toString(now->rightSon, ss);
//             }
//         }
//         void dfs(void(*func)(Node*const now))const{
//             if(root!=nullptr){
//                 _dfs(root,func);
//             }
//         }
//         void dfs(void(*func)(Node* now)){
//             if(root!=nullptr){
//                 _dfs(root,func);
//             }
//         }
//     public:
//         constexpr explicit CartesianTree(){}
//         constexpr void insert(valueType const& val){
//             Node *const newNode {new Node{}};
//             newNode->val=val;
//             while(!stack.empty()&&val<stack.top()->val){
//                 newNode->leftSon=stack.top();
//                 stack.pop();
//             }
//             if(!stack.empty()){
//                 stack.top()->rightSon=newNode;
//             }else{
//                 root = newNode;
//             }
//             stack.push(newNode);
//         }
//         constexpr valueType top()const{
//             if(root==nullptr){
//                 throw std::runtime_error("the root of the Cartesian is nullptr");
//             }
//             return root->val;
//         }
//         ~CartesianTree(){
//             dfs([](Node* now){
//                 delete now;
//             });
//         }
//         std::string toString()const{
//             std::stringstream ss;
//             ss<<"{ ";
//             if(root!=nullptr){
//                 _toString(root, ss);
//             }
//             ss<<" }";
//             return std::string(ss.str());
//         }
//     };
// }