Skip to content

Commit 4d18b70

Browse files
authored
Cartesian tree (#82)
* saving progress * saving progress * Update mono_st.rs * saving progress * saving progress * saving progress * another assert * remove * add test * asdf * finish * better * fix * uncomment * Update mono_st.rs * Update mono_range.rs * Update mono_st.rs * fix * change style * nit * change * nits * different style * golf * consistency with c++ PTC * finish doc for mono st * simplify test * add * add docs for mono range * fix typo * nit * fix * nit to docs * now ACs * cartesian tree * add indexes --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com>
1 parent 88fb8e1 commit 4d18b70

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,7 @@ path = "examples/helpers/lis_pop.rs"
207207
[[example]]
208208
name = "mono_st"
209209
path = "examples/monotonic/mono_st.rs"
210+
211+
[[example]]
212+
name = "cartesian_tree"
213+
path = "examples/monotonic/cartesian_tree.rs"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/cartesian_tree
2+
3+
use proconio::input;
4+
use programming_team_code_rust::monotonic::cartesian_tree::cart_tree;
5+
use programming_team_code_rust::monotonic::mono_st::mono_st;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
a: [u32; n],
11+
}
12+
let le = mono_st(&a, |x, y| x.lt(y));
13+
let p = cart_tree(&le);
14+
15+
println!(
16+
"{}",
17+
p.iter()
18+
.enumerate()
19+
.map(|(i, &x)| if x == usize::MAX {
20+
i.to_string()
21+
} else {
22+
x.to_string()
23+
})
24+
.collect::<Vec<_>>()
25+
.join(" ")
26+
);
27+
}

src/monotonic/cartesian_tree.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//! # Cartesian tree
2+
3+
/// Gets Vec p where p\[i\] = parent of i in cartesian tree, or usize::MAX for root
4+
///
5+
////// # Example
6+
/// ```
7+
/// use programming_team_code_rust::monotonic::mono_st::mono_st;
8+
/// use programming_team_code_rust::monotonic::cartesian_tree::cart_tree;
9+
///
10+
/// // when cmp is lt:
11+
/// let a = [2, 1, 3, 1, 1, 0, 2, 2, 1, 0, 2];
12+
/// // (---------------------------x---)
13+
/// // (---------------x---------) (x)
14+
/// // (------------x) | (------x) |
15+
/// // (---------x) | (---x) | |
16+
/// // (---x---) | (x) | | |
17+
/// // (x) | (x) | | | | |
18+
/// // | | | | | | | |
19+
/// // 0 1 2 3 4 5 6 7 8 9 10
20+
///
21+
/// let le = mono_st(&a, |x, y| x.lt(y)); // lt -> right-most min is root
22+
/// let p = cart_tree(&le); // le -> left-most min is root
23+
/// // gt -> right-most max is root
24+
/// // ge -> left-most max is root
25+
///
26+
/// assert_eq!(p, [1, 3, 1, 4, 5, 9, 7, 8, 5, usize::MAX, 9]);
27+
/// // 0 1 2 3 4 5 6 7 8 9 10
28+
/// ```
29+
///
30+
/// # Complexity
31+
/// - Time: O(n)
32+
/// - Space: O(n)
33+
pub fn cart_tree(le: &[usize]) -> Vec<usize> {
34+
let mut p = le.to_vec();
35+
for i in 0..p.len() {
36+
let mut j = i.wrapping_sub(1);
37+
while j != le[i] {
38+
if le[j] == le[i] {
39+
p[j] = i;
40+
}
41+
j = le[j];
42+
}
43+
}
44+
p
45+
}

src/monotonic/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
//! # Monotonic
2+
pub mod cartesian_tree;
23
pub mod mono_range;
34
pub mod mono_st;

0 commit comments

Comments
 (0)