1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
pub fn inversion_number(array: &[i64]) -> i64 {
count_merge(
&mut array.iter().copied().collect::<Vec<_>>(),
0..array.len(),
)
}
fn count_merge(array: &mut Vec<i64>, range: std::ops::Range<usize>) -> i64 {
let length = range.len() as i64;
if length <= 1 {
return 0;
}
let mut count = 0;
let mid = (range.start + range.end) / 2;
count += count_merge(array, range.start..mid);
count += count_merge(array, mid..range.end);
let b = array
.iter()
.skip(range.start)
.take(mid - range.start)
.copied()
.collect::<Vec<_>>();
let c = array
.iter()
.skip(mid)
.take(range.end - mid)
.copied()
.collect::<Vec<_>>();
let (mut ai, mut bi, mut ci) = (0, 0, 0);
while ai < length {
if bi < b.len() && (ci == c.len() || b[bi] <= c[ci]) {
array[range.start + ai as usize] = b[bi];
ai += 1;
bi += 1;
} else {
count += length / 2 - bi as i64;
array[range.start + ai as usize] = c[ci];
ai += 1;
ci += 1;
}
}
count
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_inversion_number() {
let array = {
let v = vec![
(vec![3, 1, 5, 4, 2], 5),
(vec![3, 5, 2, 1, 4], 6),
(vec![3, 1, 2], 2),
(vec![6, 1, 5, 8, 2, 3, 4, 7], 12),
(vec![7, 6, 1, 5, 8, 2, 3, 10, 4, 9], 19),
(
vec![
63, 16, 24, 7, 29, 57, 65, 26, 36, 32, 50, 5, 34, 1, 18, 15, 49, 9, 47, 53,
10, 35, 76, 79,
],
122,
),
(
vec![
0, 18, 35, 2, 31, 33, 32, 6, 11, 15, 36, 19, 42, 23, 9, 20, 24, 3, 10, 47,
8, 38, 5, 37, 46,
],
125,
),
];
v
};
for (input, ans) in array {
assert_eq!(inversion_number(&input), ans);
}
}
}