haar_lib/algo/
static_range_inversions_query.rs1use crate::{algo::bsearch_slice::BinarySearch, ds::fenwick_add::*};
4use std::convert::TryFrom;
5use std::ops::Range;
6
7pub struct StaticRangeInversionsQuery {
9 data: Vec<usize>,
10 qs: Vec<(usize, usize)>,
11}
12
13impl StaticRangeInversionsQuery {
14 pub fn new<T: Clone + Ord>(data: &[T]) -> Self {
16 let mut a = data.to_vec();
17 a.sort();
18 a.dedup();
19
20 let data = data.iter().map(|x| a.lower_bound(x)).collect();
21 Self { data, qs: vec![] }
22 }
23
24 pub fn add_query(&mut self, Range { start: l, end: r }: Range<usize>) {
26 self.qs.push((l, r));
27 }
28
29 pub fn solve(self) -> Vec<(Range<usize>, u64)> {
31 let n = self.data.len();
32 let width = (n as f64).sqrt() as usize;
33
34 let mut b = FenwickTreeAdd::<i64>::new(n);
35 let mut temp = 0;
36 let mut ret = vec![(0..0, 0); self.qs.len()];
37
38 let mut ord = (0..self.qs.len()).collect::<Vec<_>>();
39
40 ord.sort_by(|&i, &j| {
41 let a = self.qs[i].0 / width;
42 let b = self.qs[j].0 / width;
43
44 if a == b {
45 if a % 2 == 1 {
46 self.qs[i].1.cmp(&self.qs[j].1)
47 } else {
48 self.qs[j].1.cmp(&self.qs[i].1)
49 }
50 } else {
51 a.cmp(&b)
52 }
53 });
54
55 let mut l = self.qs[ord[0]].0;
56 let mut r = self.qs[ord[0]].0;
57
58 for id in ord {
59 while l != self.qs[id].0 || r != self.qs[id].1 {
60 if l > self.qs[id].0 {
61 l -= 1;
62 temp += b.fold(0..self.data[l]);
63 b.add(self.data[l], 1);
64 }
65 if l < self.qs[id].0 {
66 temp -= b.fold(0..self.data[l]);
67 b.add(self.data[l], -1);
68 l += 1;
69 }
70 if r < self.qs[id].1 {
71 temp += b.fold(self.data[r] + 1..self.data.len());
72 b.add(self.data[r], 1);
73 r += 1;
74 }
75 if r > self.qs[id].1 {
76 r -= 1;
77 temp -= b.fold(self.data[r] + 1..self.data.len());
78 b.add(self.data[r], -1);
79 }
80 }
81
82 ret[id] = (self.qs[id].0..self.qs[id].1, u64::try_from(temp).unwrap());
83 }
84
85 ret
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use crate::algo::inversion_number::inversion_number;
93 use my_testtools::rand_range;
94 use rand::Rng;
95
96 #[test]
97 fn test() {
98 let mut rng = rand::thread_rng();
99
100 let n = 100;
101 let a: Vec<u64> = std::iter::repeat_with(|| rng.gen()).take(n).collect();
102
103 let mut sriq = StaticRangeInversionsQuery::new(&a);
104
105 let q = 100;
106 for _ in 0..q {
107 let range = rand_range(&mut rng, 0..n);
108 sriq.add_query(range);
109 }
110
111 for (range, res) in sriq.solve() {
112 let mut temp = a[range].to_vec();
113 let ans = inversion_number(&mut temp);
114
115 assert_eq!(res, ans);
116 }
117 }
118}