use std::clone::Clone;
use std::cmp::PartialOrd;

fn merge_count_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
    a: Vec<T>,
    b: Vec<T>,
) -> (Vec<T>, usize) {
    let mut r = vec![];
    let mut i = 0;
    let mut j = 0;
    let mut inversions = 0;

    while i < a.len() && j < b.len() {
        if a[i] < b[j] {
            r.push(a[i]);
            i += 1;
        } else {
            r.push(b[j]);
            j += 1;
            inversions += a.len() - i;
        }
    }

    while i < a.len() {
        r.push(a[i]);
        i += 1;
    }

    while j < b.len() {
        r.push(b[j]);
        j += 1;
    }

    return (r, inversions);
}

pub fn merge_sort_inversions<T: Clone + PartialOrd + Copy + std::fmt::Debug>(
    v: Vec<T>,
) -> (Vec<T>, usize) {
    if v.len() <= 1 {
        return (v, 0);
    }
    let i = v.len() / 2;
    let (a, n) = merge_sort_inversions((&v[..i]).to_vec());
    let (b, m) = merge_sort_inversions((&v[i..]).to_vec());
    let (r, p) = merge_count_inversions(a, b);
    return (r, n + m + p);
}
