let max_rect heights =
  let n = Array.length heights in
  let stack = ref [] in
  let best = ref 0 in
  for i = 0 to n do
    let h = if i = n then 0 else heights.(i) in
    let cont = ref true in
    while !cont do
      match !stack with
      | top :: rest when heights.(top) > h ->
        let height = heights.(top) in
        stack := rest;
        let width = match !stack with
          | [] -> i
          | t :: _ -> i - t - 1
        in
        let area = height * width in
        if area > !best then best := area
      | _ -> cont := false
    done;
    if i < n then stack := i :: !stack
  done;
  !best

;;

max_rect [| 2; 1; 5; 6; 2; 3 |]
