Skip to content

Commit 3f89810

Browse files
committed
Merge branch 'main' into compress_tree
2 parents 38343f0 + 595a438 commit 3f89810

File tree

7 files changed

+207
-5
lines changed

7 files changed

+207
-5
lines changed

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,11 @@ path = "examples/monotonic/mono_st.rs"
211211
[[example]]
212212
name = "hld_aux_tree"
213213
path = "examples/graphs/hld_aux_tree.rs"
214+
215+
[[example]]
216+
name = "count_rects"
217+
path = "examples/monotonic/count_rects.rs"
218+
219+
[[example]]
220+
name = "cartesian_tree"
221+
path = "examples/monotonic/cartesian_tree.rs"

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+
}

examples/monotonic/count_rects.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/library/7/DPL/all/DPL_3_B
2+
3+
use proconio::input;
4+
use programming_team_code_rust::monotonic::count_rects::count_rects;
5+
6+
fn main() {
7+
input! {
8+
n: usize,
9+
m: usize,
10+
grid: [[u32; m]; n],
11+
}
12+
let grid = grid
13+
.iter()
14+
.map(|row| row.iter().map(|&num| num == 0).collect::<Vec<_>>())
15+
.collect::<Vec<_>>();
16+
let cnt = count_rects(&grid);
17+
18+
{
19+
let mut pref_sum = vec![vec![0; m + 1]; n + 1];
20+
for i in 0..n {
21+
for j in 0..m {
22+
pref_sum[i + 1][j + 1] =
23+
grid[i][j] as i64 + pref_sum[i + 1][j] + pref_sum[i][j + 1] - pref_sum[i][j];
24+
}
25+
}
26+
for len_i in 1..=5.min(n) {
27+
for len_j in 1..5.min(m) {
28+
let mut cnt_good_rects = 0;
29+
for i in 0..=n - len_i {
30+
for j in 0..=m - len_j {
31+
let cnt_rect = pref_sum[i + len_i][j + len_j]
32+
- pref_sum[i + len_i][j]
33+
- pref_sum[i][j + len_j]
34+
+ pref_sum[i][j];
35+
if cnt_rect == len_i as i64 * len_j as i64 {
36+
cnt_good_rects += 1;
37+
}
38+
}
39+
}
40+
assert_eq!(cnt_good_rects, cnt[len_i][len_j]);
41+
}
42+
}
43+
}
44+
45+
let mut res = 0;
46+
for (i, row) in cnt.iter().enumerate().skip(1) {
47+
for (j, &num) in row.iter().enumerate().skip(1) {
48+
if num > 0 {
49+
res = res.max(i as u64 * j as u64);
50+
}
51+
}
52+
}
53+
println!("{}", res);
54+
}

src/data_structures/trie.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! # Trie
22
33
const ALPHABET_SIZE: usize = 26;
4-
const FIRST_CHAR: char = 'A';
4+
const FIRST_CHAR: usize = 'A' as usize;
55

66
#[derive(Default)]
77
struct Node {
@@ -45,7 +45,7 @@ impl Trie {
4545
pub fn insert(&mut self, s: &[char]) {
4646
let mut v = 0;
4747
for &ch in s {
48-
let idx = (ch as u8 - FIRST_CHAR as u8) as usize;
48+
let idx = ch as usize - FIRST_CHAR;
4949
if self.t[v].next[idx].is_none() {
5050
self.t[v].next[idx] = Some(self.t.len());
5151
self.t.push(Node::default());
@@ -63,11 +63,12 @@ impl Trie {
6363
pub fn find(&self, s: &[char]) -> usize {
6464
let mut v = 0;
6565
for &ch in s {
66-
let idx = (ch as u8 - FIRST_CHAR as u8) as usize;
67-
if self.t[v].next[idx].is_none() {
66+
let idx = ch as usize - FIRST_CHAR;
67+
if let Some(u) = self.t[v].next[idx] {
68+
v = u;
69+
} else {
6870
return 0;
6971
}
70-
v = self.t[v].next[idx].unwrap();
7172
}
7273
self.t[v].cnt_words
7374
}

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/count_rects.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//! # Count Rectangles
2+
3+
use crate::monotonic::mono_range::mono_range;
4+
use crate::monotonic::mono_st::mono_st;
5+
6+
/// grid is a n-by-m boolean array
7+
///
8+
/// Gets an (n+1)-by-(m+1) vec cnt where cnt\[i\]\[j\] = the number of times an i-by-j subrectangle
9+
/// appears in the grid such that all i*j cells in the subrectangle are true.
10+
///
11+
/// cnt\[i\]\[0\] and cnt\[0\]\[j\] will contain garbage numbers.
12+
///
13+
/// # Example
14+
/// ```
15+
/// use programming_team_code_rust::monotonic::count_rects::count_rects;
16+
///
17+
/// let mut cnt = count_rects(&[vec![true, true, false],
18+
/// vec![true, true, true]]);
19+
///
20+
/// // remove garbage values
21+
/// cnt.drain(0..1);
22+
/// for i in 0..cnt.len() {
23+
/// cnt[i].drain(0..1);
24+
/// }
25+
///
26+
/// assert_eq!(cnt, [[5, 3, 1],
27+
/// [2, 1, 0]]);
28+
///
29+
/// assert!(std::panic::catch_unwind(|| count_rects(&[])).is_err());
30+
/// ```
31+
///
32+
/// # Complexity
33+
/// - Time: O(nm)
34+
/// - Space: O(nm)
35+
pub fn count_rects(grid: &[Vec<bool>]) -> Vec<Vec<i32>> {
36+
let (n, m) = (grid.len(), grid[0].len());
37+
let mut cnt = vec![vec![0; m + 1]; n + 1];
38+
let mut h = vec![0; m];
39+
for row in grid {
40+
for j in 0..m {
41+
h[j] = row[j] as usize * (h[j] + 1);
42+
}
43+
let le = mono_st(&h, |x, y| x.lt(y));
44+
let ri = mono_range(&le);
45+
for j in 0..m {
46+
let (cnt_l, cnt_r) = (j - le[j].wrapping_add(1), ri[j] - j - 1);
47+
cnt[h[j]][cnt_l + cnt_r + 1] += 1;
48+
cnt[h[j]][cnt_l] -= 1;
49+
cnt[h[j]][cnt_r] -= 1;
50+
}
51+
}
52+
for row in cnt.iter_mut().skip(1) {
53+
for _ in 0..2 {
54+
for j in (1..m).rev() {
55+
row[j] += row[j + 1];
56+
}
57+
}
58+
}
59+
for i in (1..n).rev() {
60+
for j in 1..=m {
61+
cnt[i][j] += cnt[i + 1][j];
62+
}
63+
}
64+
cnt
65+
}

src/monotonic/mod.rs

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

0 commit comments

Comments
 (0)