let count_inv arr =
  let n = Array.length arr in
  let temp = Array.make n 0 in
  let count = ref 0 in
  let rec merge lo mid hi =
    let i = ref lo and j = ref (mid + 1) and k = ref lo in
    while !i <= mid && !j <= hi do
      if arr.(!i) <= arr.(!j) then begin
        temp.(!k) <- arr.(!i);
        i := !i + 1
      end else begin
        temp.(!k) <- arr.(!j);
        count := !count + (mid - !i + 1);
        j := !j + 1
      end;
      k := !k + 1
    done;
    while !i <= mid do
      temp.(!k) <- arr.(!i);
      i := !i + 1; k := !k + 1
    done;
    while !j <= hi do
      temp.(!k) <- arr.(!j);
      j := !j + 1; k := !k + 1
    done;
    for x = lo to hi do
      arr.(x) <- temp.(x)
    done
  and sort lo hi =
    if lo < hi then begin
      let mid = (lo + hi) / 2 in
      sort lo mid;
      sort (mid + 1) hi;
      merge lo mid hi
    end
  in
  sort 0 (n - 1);
  !count

;;

count_inv [|8; 4; 2; 1; 3; 5; 7; 6|]
