Skip to content

Commit 88fb8e1

Browse files
authored
Mono st (#80)
* 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 --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com>
1 parent 2fd60b0 commit 88fb8e1

File tree

6 files changed

+176
-0
lines changed

6 files changed

+176
-0
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,7 @@ path = "examples/helpers/lis_yosupo.rs"
203203
[[example]]
204204
name = "lis_pop"
205205
path = "examples/helpers/lis_pop.rs"
206+
207+
[[example]]
208+
name = "mono_st"
209+
path = "examples/monotonic/mono_st.rs"

examples/monotonic/mono_st.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/staticrmq
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::rmq::RMQ;
5+
use programming_team_code_rust::monotonic::mono_range::mono_range;
6+
use programming_team_code_rust::monotonic::mono_st::mono_st;
7+
8+
fn main() {
9+
input! {
10+
n: usize,
11+
q: usize,
12+
a: [u32; n],
13+
}
14+
15+
let rmq = RMQ::new(
16+
&(0..n).map(|i| (i, i)).collect::<Vec<_>>(),
17+
|(min_i1, max_i1), (min_i2, max_i2)| {
18+
let min_idx = if a[min_i1] < a[min_i2] {
19+
min_i1
20+
} else {
21+
min_i2
22+
};
23+
let max_idx = if a[max_i1] > a[max_i2] {
24+
max_i1
25+
} else {
26+
max_i2
27+
};
28+
(min_idx, max_idx)
29+
},
30+
);
31+
32+
let compares = vec![
33+
|x: u32, y: u32| -> bool { x.le(&y) },
34+
|x: u32, y: u32| -> bool { x.lt(&y) },
35+
|x: u32, y: u32| -> bool { x.ge(&y) },
36+
|x: u32, y: u32| -> bool { x.gt(&y) },
37+
];
38+
39+
let mut le = Vec::new();
40+
let mut ri = Vec::new();
41+
for &cmp in &compares {
42+
le.push(mono_st(&a, |&x, &y| cmp(x, y)));
43+
ri.push(mono_range(le.last().unwrap()));
44+
}
45+
let le = le;
46+
let ri = ri;
47+
48+
for curr_le in &le {
49+
let mut count_index = vec![0; n];
50+
for i in 0..n {
51+
let mut j = i.wrapping_sub(1);
52+
while j != curr_le[i] {
53+
count_index[j] += 1;
54+
j = curr_le[j];
55+
}
56+
}
57+
let mut j = n.wrapping_sub(1);
58+
while j != usize::MAX {
59+
count_index[j] += 1;
60+
j = curr_le[j];
61+
}
62+
assert_eq!(count_index, vec![1; n]);
63+
}
64+
65+
for _ in 0..q {
66+
input! {
67+
l: usize,
68+
r: usize,
69+
}
70+
71+
let (min_idx, max_idx) = rmq.query(l..r);
72+
73+
for i in 0..4 {
74+
let idx = if i < 2 { min_idx } else { max_idx };
75+
let rmq_res = rmq.query(le[i][idx].wrapping_add(1)..ri[i][idx]);
76+
assert_eq!(a[if i < 2 { rmq_res.0 } else { rmq_res.1 }], a[idx]);
77+
if le[i][idx] != usize::MAX {
78+
assert!(compares[i](a[le[i][idx]], a[idx]));
79+
}
80+
if ri[i][idx] < n {
81+
assert!(!compares[i](a[idx], a[ri[i][idx]]));
82+
}
83+
}
84+
85+
println!("{}", a[min_idx]);
86+
}
87+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
pub mod data_structures;
33
pub mod graphs;
44
pub mod helpers;
5+
pub mod monotonic;
56
pub mod numbers;
67
pub mod strings;

src/monotonic/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//! # Monotonic
2+
pub mod mono_range;
3+
pub mod mono_st;

src/monotonic/mono_range.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! # Monotonic Range
2+
3+
/// Gets vec ri where ri\[i\] = smallest index such that i < ri\[i\] && !a\[i\].cmp(&a\[ri\[i\]\]), or n
4+
///
5+
/// # Example
6+
/// ```
7+
/// use programming_team_code_rust::monotonic::mono_st::mono_st;
8+
/// use programming_team_code_rust::monotonic::mono_range::mono_range;
9+
///
10+
/// let a: Vec<u32> = vec![3, 1, 2, 2];
11+
///
12+
/// let le = mono_st(&a, |x, y| x.lt(y));
13+
/// let ri = mono_range(&le);
14+
/// assert_eq!(ri, [1, 4, 3, 4]);
15+
/// ```
16+
///
17+
/// # Complexity
18+
/// - Time: O(n)
19+
/// - Space: O(n)
20+
pub fn mono_range(le: &[usize]) -> Vec<usize> {
21+
let mut ri = vec![le.len(); le.len()];
22+
for i in 0..le.len() {
23+
let mut j = i.wrapping_sub(1);
24+
while j != le[i] {
25+
ri[j] = i;
26+
j = le[j];
27+
}
28+
}
29+
ri
30+
}

src/monotonic/mono_st.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//! # Monotonic Stack
2+
3+
/// Gets vec le where le\[i\] = largest index such that le\[i\] < i && a\[le\[i\]\].cmp(&a\[i\]), or usize::MAX
4+
///
5+
/// # Example
6+
/// ```
7+
/// use programming_team_code_rust::monotonic::mono_st::mono_st;
8+
///
9+
/// let a: Vec<u32> = vec![3, 1, 2, 2];
10+
/// let n = a.len();
11+
///
12+
/// assert_eq!(mono_st(&a, |x, y| x.lt(y)), [usize::MAX, usize::MAX, 1, 1]);
13+
/// assert_eq!(mono_st(&a, |x, y| x.le(y)), [usize::MAX, usize::MAX, 1, 2]);
14+
/// assert_eq!(mono_st(&a, |x, y| x.gt(y)), [usize::MAX, 0, 0, 0]);
15+
/// assert_eq!(mono_st(&a, |x, y| x.ge(y)), [usize::MAX, 0, 0, 2]);
16+
///
17+
/// // simulate popping off stack for single index
18+
/// let le = mono_st(&a, |x, y| x.lt(y));
19+
/// let mut seen_index = vec![0; n];
20+
/// for i in 0..n {
21+
/// let mut j = i.wrapping_sub(1);
22+
/// while j != le[i] {
23+
/// let range = le[j].wrapping_add(1)..j; // for all indexes k in range: !cmp(&a[k], &a[j])
24+
/// seen_index[j] += 1;
25+
/// j = le[j];
26+
/// }
27+
/// }
28+
///
29+
/// // clear the stack at the end
30+
/// let mut j = n.wrapping_sub(1);
31+
/// while j != usize::MAX {
32+
/// seen_index[j] += 1;
33+
/// j = le[j];
34+
/// }
35+
///
36+
/// assert_eq!(seen_index, vec![1; n]);
37+
/// ```
38+
///
39+
/// # Complexity
40+
/// - Time: O(n)
41+
/// - Space: O(n)
42+
pub fn mono_st<T: Ord, F: Fn(&T, &T) -> bool>(a: &[T], cmp: F) -> Vec<usize> {
43+
let mut le = vec![0; a.len()];
44+
for i in 0..a.len() {
45+
le[i] = i.wrapping_sub(1);
46+
while le[i] != usize::MAX && !cmp(&a[le[i]], &a[i]) {
47+
le[i] = le[le[i]];
48+
}
49+
}
50+
le
51+
}

0 commit comments

Comments
 (0)