competitive_programming_rs/math/
max_rectangle.rs1pub mod max_rectangle {
2 use std::cmp;
3 use std::collections::VecDeque;
4
5 fn calc(hist: &[usize]) -> usize {
6 let n = hist.len();
7 let mut ans = 0;
8 let mut q: VecDeque<(usize, usize)> = VecDeque::new();
9
10 for (i, &hist) in hist.iter().enumerate() {
11 let mut reachable_min = i;
12 while let Some((pos, height)) = q.pop_front() {
13 if height <= hist {
14 q.push_front((pos, height));
15 break;
16 }
17 reachable_min = pos;
18 ans = cmp::max(ans, (i - reachable_min) * height);
19 }
20
21 if q.is_empty() || q.iter().next().unwrap().1 < hist {
22 q.push_front((reachable_min, hist));
23 }
24 }
25 while let Some((pos, height)) = q.pop_front() {
26 ans = cmp::max(ans, (n - pos) * height);
27 }
28 ans
29 }
30
31 pub fn maximize(map: &[Vec<bool>]) -> usize {
32 let h = map.len();
33 let w = map[0].len();
34 let mut hist = vec![vec![0; w]; h];
35 for i in 0..h {
36 for j in 0..w {
37 if !map[i][j] {
38 continue;
39 }
40 if i == 0 {
41 hist[i][j] = 1;
42 } else {
43 hist[i][j] = hist[i - 1][j] + 1;
44 }
45 }
46 }
47
48 let mut ans = 0;
49 for hist in hist.iter() {
50 ans = cmp::max(ans, calc(hist));
51 }
52 ans
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use super::*;
59 use crate::utils::test_helper::Tester;
60
61 #[test]
62 fn solve_dpl_3_b() {
63 let tester = Tester::new("./assets/DPL_3_B/in/", "./assets/DPL_3_B/out/");
64
65 tester.test_solution(|sc| {
66 let h: usize = sc.read();
67 let w: usize = sc.read();
68
69 let mut c = vec![vec![false; w]; h];
70 for i in 0..h {
71 for j in 0..w {
72 c[i][j] = sc.read::<usize>() == 0;
73 }
74 }
75
76 let ans = max_rectangle::maximize(&c);
77 sc.write(format!("{}\n", ans));
78 });
79 }
80}