Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 01f1fa5

Browse files
author
Oleksandr Kulkov
authored
Cartesian tree off list of (xi, yi) pairs
1 parent c7295b3 commit 01f1fa5

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/data_structures/treap.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ struct item {
106106
item *l, *r;
107107
item () { }
108108
item (int key) : key(key), prior(rand()), l(NULL), r(NULL) { }
109+
item (int key, int prior) : key(key), prior(prior), l(NULL), r(NULL) { }
109110
};
110111
typedef item* pitem;
111112
```
@@ -229,6 +230,53 @@ pitem build (int * a, int n) {
229230

230231
Note: calling `upd_cnt(t)` is only necessary if you need the subtree sizes.
231232

233+
The approach above always provides a perfectly balanced tree, which is generally good for practical purposes, but at the cost of not preserving the priorities that were initially assigned to each node. Thus, this approach is not feasible to solve the following problem:
234+
235+
!!! example "[acmsguru - Cartesian Tree](https://codeforces.com/problemsets/acmsguru/problem/99999/155)"
236+
Given a sequence of pairs $(x_i, y_i)$, construct a cartesian tree on them. All $x_i$ and all $y_i$ are unique.
237+
238+
Note that in this problem priorities are not random, hence just inserting vertices one by one could provide a quadratic solution.
239+
240+
One of possible solutions here is to find for each element the closest elements to the left and to the right which have a smaller priority than this element. Among these two elements, the one with the larger priority must be the parent of the current element.
241+
242+
This problem is solvable with a [minimum stack](./stack_queue_modification.md) modification in linear time:
243+
244+
```cpp
245+
void connect(auto from, auto to) {
246+
vector<pitem> st;
247+
for(auto it: ranges::subrange(from, to)) {
248+
while(!st.empty() && st.back()->prior > it->prior) {
249+
st.pop_back();
250+
}
251+
if(!st.empty()) {
252+
if(!it->p || it->p->prior < st.back()->prior) {
253+
it->p = st.back();
254+
}
255+
}
256+
st.push_back(it);
257+
}
258+
}
259+
260+
pitem build(int *x, int *y, int n) {
261+
vector<pitem> nodes(n);
262+
for(int i = 0; i < n; i++) {
263+
nodes[i] = new item(x[i], y[i]);
264+
}
265+
connect(nodes.begin(), nodes.end());
266+
connect(nodes.rbegin(), nodes.rend());
267+
for(int i = 0; i < n; i++) {
268+
if(nodes[i]->p) {
269+
if(nodes[i]->p->key < nodes[i]->key) {
270+
nodes[i]->p->r = nodes[i];
271+
} else {
272+
nodes[i]->p->l = nodes[i];
273+
}
274+
}
275+
}
276+
return nodes[min_element(y, y + n) - y];
277+
}
278+
```
279+
232280
## Implicit Treaps
233281
234282
Implicit treap is a simple modification of the regular treap which is a very powerful data structure. In fact, implicit treap can be considered as an array with the following procedures implemented (all in $O (\log N)$ in the online mode):

0 commit comments

Comments
 (0)