The Cartesian Tree is a data structure that maintains a sequence of numbers by maintaining a binary tree.

Specifically, in the binary tree, each node stores an element in . The binary tree satisfies that the in-order traversal order of the nodes matches their order in the sequence, and the element in each node is less than or equal to the element in its parent.

This requires space.

Build

Build builds a Cartesian Tree for in time and space.

Algorithm

  1. Build a Cartesian Tree for recursively, and let denote the right spine of the Cartesian Tree, from the root to the bottom.
  2. Let be the integer in such that . Cut the edge between node and node , and let node be the new right child of node , node be the new left child of node .

Using a Monotonic Queue to maintain the right spine yields an algorithm that solves the problem in time and space.

void build(int n, const std::vector<int> &a) {
	lch.assign(n, -1), rch.assign(n, -1);
	std::vector<int> stk;
 
	for (int i = 0; i < n; i++) {
		while (!stk.empty() && a[stk.back()] < a[i]) {
			rch[stk.back()] = std::exchange(lch[i], stk.back());
			stk.pop_back();
		}
		stk.push_back(i);
	}
	while (stk.size() > 1) {
		int i = stk.back();
		stk.pop_back();
 
		rch[stk.back()] = i;
	}
	root = stk[0];
}