1use std::{
2 iter::{Product, Sum},
3 ops::{Add, AddAssign},
4};
5
6pub trait Inversion {
7 fn inversion<I: Add<I> + for<'a> AddAssign<&'a I> + Sum<I> + Product<I>>(
8 &self,
9 ) -> I;
10}
11
12impl<T: Ord> Inversion for [T] {
13 fn inversion<I: Add<I> + for<'a> AddAssign<&'a I> + Sum<I> + Product<I>>(
14 &self,
15 ) -> I {
16 let n = self.len();
17 let ord = {
18 let mut ord: Vec<_> = (0..n).collect();
19 ord.sort_unstable_by(|&il, &ir| {
20 self[il].cmp(&self[ir]).then_with(|| il.cmp(&ir))
21 });
22 ord
23 };
24
25 let zero = || None.into_iter().sum::<I>();
26 let one = || None.into_iter().product::<I>();
27 let mut res = zero();
28 let mut sum: Vec<_> = (0..=n).map(|_| zero()).collect();
29 for i in ord.iter().map(|&i| i + 1) {
30 {
31 let mut i = i;
32 while i <= n {
33 res += &sum[i];
34 i += i & i.wrapping_neg();
35 }
36 }
37 {
38 let mut i = i;
39 while i > 0 {
40 sum[i] += &one();
41 i -= i & i.wrapping_neg();
42 }
43 }
44 }
45
46 res
47 }
48}
49
50#[test]
51fn sanity_check() {
52 assert_eq!([1, 5, 4, 2, 3].inversion::<usize>(), 5);
53 assert_eq!([1, 2, 3, 4, 5].inversion::<usize>(), 0);
54 assert_eq!([5, 4, 3, 2, 1].inversion::<usize>(), 10);
55 assert_eq!([1, 1, 1, 1, 1].inversion::<usize>(), 0);
56
57 let empty: [(); 0] = [];
58 assert_eq!(empty.inversion::<usize>(), 0);
59}