cartesian_tree.hpp¶
#include "noya/cartesian_tree.hpp"
#ifndef NOYA_CARTESIAN_TREE_HPP
#define NOYA_CARTESIAN_TREE_HPP 1
#include <cassert>
#include <vector>
namespace noya {
/// @brief Cartesian tree where each node is the minimum of its subtree. Equal values prefer the leftmost.
struct min_cartesian_tree {
int n, rt;
std::vector<int> par, lef, rig;
template <class T> void build(int n_, T *as) {
assert(n_ >= 1);
n = n_;
rt = 0;
par.assign(n, -1);
lef.assign(n, -1);
rig.assign(n, -1);
int top = 0;
std::vector<int> stack(n, 0);
for (int u = 1; u < n; ++u) {
if (as[stack[top]] > as[u]) {
for (; top >= 1 && as[stack[top - 1]] > as[u]; --top) {
}
if (top == 0) {
rt = par[lef[u] = stack[top]] = u;
} else {
par[lef[u] = stack[top]] = u;
rig[par[u] = stack[top - 1]] = u;
}
stack[top] = u;
} else {
rig[par[u] = stack[top]] = u;
stack[++top] = u;
}
}
}
template <class T> void build(const T &as) { build(as.size(), as.data()); }
};
/// @brief Cartesian tree where each node is the maximum of its subtree. Equal values prefer the leftmost.
struct max_cartesian_tree {
int n, rt;
std::vector<int> par, lef, rig;
template <class T> void build(int n_, T *as) {
assert(n_ >= 1);
n = n_;
rt = 0;
par.assign(n, -1);
lef.assign(n, -1);
rig.assign(n, -1);
int top = 0;
std::vector<int> stack(n, 0);
for (int u = 1; u < n; ++u) {
if (as[stack[top]] < as[u]) {
for (; top >= 1 && as[stack[top - 1]] < as[u]; --top) {
}
if (top == 0) {
rt = par[lef[u] = stack[top]] = u;
} else {
par[lef[u] = stack[top]] = u;
rig[par[u] = stack[top - 1]] = u;
}
stack[top] = u;
} else {
rig[par[u] = stack[top]] = u;
stack[++top] = u;
}
}
}
template <class T> void build(const T &as) { build(as.size(), as.data()); }
};
} // namespace noya
#endif // NOYA_CARTESIAN_TREE_HPP
#include <cassert>
#include <vector>
namespace noya {
/// @brief Cartesian tree where each node is the minimum of its subtree. Equal values prefer the leftmost.
struct min_cartesian_tree {
int n, rt;
std::vector<int> par, lef, rig;
template <class T> void build(int n_, T *as) {
assert(n_ >= 1);
n = n_;
rt = 0;
par.assign(n, -1);
lef.assign(n, -1);
rig.assign(n, -1);
int top = 0;
std::vector<int> stack(n, 0);
for (int u = 1; u < n; ++u) {
if (as[stack[top]] > as[u]) {
for (; top >= 1 && as[stack[top - 1]] > as[u]; --top) {
}
if (top == 0) {
rt = par[lef[u] = stack[top]] = u;
} else {
par[lef[u] = stack[top]] = u;
rig[par[u] = stack[top - 1]] = u;
}
stack[top] = u;
} else {
rig[par[u] = stack[top]] = u;
stack[++top] = u;
}
}
}
template <class T> void build(const T &as) { build(as.size(), as.data()); }
};
/// @brief Cartesian tree where each node is the maximum of its subtree. Equal values prefer the leftmost.
struct max_cartesian_tree {
int n, rt;
std::vector<int> par, lef, rig;
template <class T> void build(int n_, T *as) {
assert(n_ >= 1);
n = n_;
rt = 0;
par.assign(n, -1);
lef.assign(n, -1);
rig.assign(n, -1);
int top = 0;
std::vector<int> stack(n, 0);
for (int u = 1; u < n; ++u) {
if (as[stack[top]] < as[u]) {
for (; top >= 1 && as[stack[top - 1]] < as[u]; --top) {
}
if (top == 0) {
rt = par[lef[u] = stack[top]] = u;
} else {
par[lef[u] = stack[top]] = u;
rig[par[u] = stack[top - 1]] = u;
}
stack[top] = u;
} else {
rig[par[u] = stack[top]] = u;
stack[++top] = u;
}
}
}
template <class T> void build(const T &as) { build(as.size(), as.data()); }
};
} // namespace noya