Problem:
Score : 300 points

Problem Statement

N persons are standing in a row. The height of the i-th person from the front is A_i.

We want to have each person stand on a stool of some heights - at least zero - so that the following condition is satisfied for every person:

Condition: Nobody in front of the person is taller than the person. Here, the height of a person includes the stool.

Find the minimum total height of the stools needed to meet this goal.

Constraints

1 \leq N \leq 2\times 10^5

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 \ldots A_N

Output

Print the minimum total height of the stools needed to meet the goal.

Sample Input 1

5
2 1 5 4 3

Sample Output 1

4

If the persons stand on stools of heights 0, 1, 0, 1, and 2, respectively, their heights will be 2, 2, 5, 5, and 5, satisfying the condition.

We cannot meet the goal with a smaller total height of the stools.

Sample Input 2

5
3 3 3 3 3

Sample Output 2

0

Giving a stool of height 0 to everyone will work.

Solution in OCaml (4.10.0) (judge verdict: Accepted)

open Batteries
open Printf

let ($) g f x = g (f x)

let swap = Tuple2.swap

let s2i = int_of_string
let i2s = string_of_int
let s2f = float_of_string
let f2s = string_of_float
let f2i = int_of_float
let i2f = float_of_int 

let c2a = int_of_char
let a2c = char_of_int

let c2i c = c2a c - 48
let i2c i = a2c (i + 48)

let c2s = String.of_char
let s2cl = String.to_list
let cl2s = String.of_list

let puts s = print_endline s
let putw ?yn:(yn=("Yes", "No")) b = puts (if b then fst yn else snd yn)
let puti i = puts @@ i2s i



module StaleList = struct
  include List

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let nempty l = not @@ is_empty l

  let hdop l = if nempty l then Some (hd l) else None

  (* let taker = drop *)
  let takewh = take_while

  (* let dropr = take *)
  let dropwh = drop_while

  let split_by = span

  let chunk = ntake

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  let partition_to_map f l =
    foldr (fun x m -> Map.modify_opt (f x) (function
      | None -> Some [x] 
      | Some [] -> Some [x] 
      | Some vl -> Some (x::vl)) m) Map.empty l;;

  let scanl f z ls =
    let rec loop acl acc = function
      | [] -> rev acl
      | h::t ->
        let r = f acc h in
        loop (r::acl) r t
    in loop [] z ls

  let scanr f z ls =
    let rec loop acl acc = function
      | [] -> acl 
      | h::t ->
        let r = f h acc in
        loop (r::acl) r t
    in loop [] z (rev ls)

  (* let scanli = scan_lefti *)
  (* let scanri = scan_righti *)
  
  let flatmap = concat_map

  let zipf = map2
  let zipfi = map2i

end

module L = StaleList

module StaleArray = struct
  include Array 

  let nmem x l = not @@ mem x l

  let len = length
  let size = length
  let is_empty r = len r = 0
  let nempty r = len r > 0

  let take n r = left r n
  let taker n r = right r n

  let takeb x r =
    let l = len r in
    let rec loop i =
      if i >= l then r
      else if r.(i) = x then take i r
      else loop (i + 1)
    in loop 0
     
  (* let takewh = take_while *)

  let drop n r = tail r n
  let dropr n r = take ((len r) - n) r
  (* let dropwh = drop_while *)

  let index_of x r =
    let l = len r in
    let rec loop i =
      if i >= l then None
      else if r.(i) = x then Some i
      else loop (i + 1)
    in loop 0

  (* let split_by = span *)

  (* let chunk = ntake *)

  let foldl = fold_left
  let foldli = fold_lefti
  let foldr f z l = fold_right f l z
  let foldri f z l = fold_righti f l z

  (* let partition_to_map f l = *)
  (*   foldr (fun x m -> Map.modify_opt (f x) (function *)
  (*     | None -> Some [x]  *)
  (*     | Some [] -> Some [x]  *)
  (*     | Some vl -> Some (x::vl)) m) Map.empty l;; *)

  (* let scanl = scan_left *)
  (* let scanli = scan_lefti *)
  (* let scanr = scan_right *)
  (* let scanri = scan_righti *)
  
  let concat2 = append
  
  let flatmap (f : 'a -> 'b array) a =
    map f a |> enum |> L.of_enum |> concat

  let zipf = map2
  (* let zipfi = map2i *)

end

module A = StaleArray

module StaleString = struct
  include String

  let len = length

  let replace_chars = map
  let map = replace

  let maptol f s = L.map f (s2cl s)
  let maptoli f s = L.map f (s2cl s)

  let zipf f a b = L.zipf f (s2cl a) (s2cl b)
  let zipfi f a b = L.zipfi f (s2cl a) (s2cl b)

  let mkstr f sep ls =
    L.foldl (fun acc x -> acc ^ sep ^ (f x)) (f @@ L.hd ls) (List.tl ls)

end

module S = StaleString

let spsp s = S.split_on_char ' ' s


module StaleSortedSet = struct
  include Set

  module Make (Ord : Set.OrderedType) = struct
    include Set.Make(Ord)

    let nmem x st = not @@ mem x st

    let foldl f s z = fold (fun x a -> f a x) z s

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let foldl f s z = fold (fun x a -> f a x) z s

  let size = cardinal
end

module Ss = StaleSortedSet

module StaleSortedMap  = struct
  include Map

  module Make (Ord : Map.OrderedType) = struct
    include Map.Make(Ord)

    let nmem x st = not @@ mem x st

    let get = find
    let get_or x d m = find_default d x m

    let size = cardinal
  end

  let nmem x st = not @@ mem x st

  let get = find
  let get_or x d m = find_default d x m

  let size = cardinal
end

module Ms = StaleSortedMap


module StaleRange = struct

  type t = Range of int * int

  let make lb ub = Range (lb, ub)

  let to_list r =
    let Range (lb, ub) = r in
    L.make (ub - lb) ((+) lb) 

  let to_array r =
    let Range (lb, ub) = r in
      A.make (ub - lb) ((+) lb)

  let iter r f = 
    let Range (lb, ub) = r in
    for i = lb to ub do f i done

  let iter2 r1 r2 f =
    let Range (lb1, ub1) = r1 and Range (lb2, ub2) = r2 in
      for i = lb1 to ub2 do
        for j = lb2 to ub2 do
          f i j
        done
      done
end

module R = StaleRange

let (---) lb ub = R.make lb ub
let (--^) lb ub = R.make lb (ub - 1)

module StaleGenericAlgorithms = struct

  let set_power ls =
    let rec loop ls pls =
      match ls with
      | [] -> pls
      | hd::tl -> loop tl (L.flatmap (fun p -> [p; hd::p]) pls)
    in loop ls [[]]

  let rec bsearch_max_int f lb ub =
    if lb >= ub then (if f lb then lb else (lb - 1))
    else (
      let m = (lb + ub) / 2 in
      if f m then bsearch_max_int f (m + 1) ub
      else bsearch_max_int f lb m
    )

  let partial_sum n ls =
    let rec loop s k = function
      | [] -> s
      | h::t ->
        if k >= n then s
        else loop (s + h) (k + 1) t
    in
    loop 0 0 ls

end

module Gal = StaleGenericAlgorithms

let rds () = read_line ()

let rdi () = s2i @@ rds ()

let rdhs () = spsp @@ rds ()
let rdhi () = rdhs () |> L.map s2i

let rdhf () = rdhs () |> L.map s2f

let rdf2 () = match rdhf () with
| a::b::_ -> (a, b)
| _ -> (0., 0.)

let rdf3 () = match rdhf () with
| a::b::c::_ -> (a, b, c)
| _ -> (0., 0., 0.)

let rdf4 () = match rdhf () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0., 0., 0., 0.)

let rds2 () = match rdhs () with
  | a::b::_ -> (a, b)
  | _ -> ("", "")

let rdi2 () = match rdhi () with
  | a::b::_ -> (a, b)
  | _ -> (0, 0)

let rdi3 () = match rdhi () with
| a::b::c::_ -> (a, b, c)
| _ -> (0, 0, 0)

let rdi4 () = match rdhi () with
| a::b::c::d::_ -> (a, b, c, d)
| _ -> (0, 0, 0, 0)

let rdi5 () = match rdhi () with
| a::b::c::d::e::_ -> (a, b, c, d, e)
| _ -> (0, 0, 0, 0, 0)

let rdv n rf =
  let rec loop n =
    if n <= 0 then []
    else (
      let s = rf () in
      s::(loop (n - 1))
    )
  in loop n

let rdvi n = rdv n rdi
let rdvi2 n = rdv n rdi2
let rdvi3 n = rdv n rdi3
let rdvi4 n = rdv n rdi4


let print_list aa = 
  printf "[ "; aa |> L.iter (fun a -> printf "%d " a); puts "]"

let print_array aa = 
  printf "[ "; aa |> A.iter (fun a -> printf "%d " a); puts "]"

let print_carray aa = 
  printf "[ "; aa |> A.iter (fun a -> printf "%c " a); puts "]"

let print_matrix mat =
  puts "----";
  mat |> A.iter (fun r -> print_carray r);
  puts "----"


let _ =
  let n = rdi () in
  let aa = rdhi () in

  let rec steps sum mx = function
  | [] -> sum
  | h::t -> 
    if h < mx then
      let r = mx - h in
      steps (sum + r) mx t
    else
      steps sum h t
  in

    
  puti @@ steps 0 0 aa