competitive/algorithm/
mo_algorithm.rs1#[macro_export]
14macro_rules! mo_algorithm {
15 (
16 $lr:expr,
17 ($l:ident, $r:ident),
18 |$i:tt| $inc:expr,
19 |$d:tt| $dec:expr,
20 |$a:tt| $answer:expr $(,)?
21 ) => {{
22 $crate::mo_algorithm!(
23 $lr,
24 ($l, $r),
25 |$i| $inc,
26 |$d| $dec,
27 |$d| $dec,
28 |$i| $inc,
29 |$a| $answer
30 );
31 }};
32 (
33 $lr:expr,
34 ($l:ident, $r:ident),
35 |$il:tt| $incl:expr,
36 |$dl:tt| $decl:expr,
37 |$ir:tt| $incr:expr,
38 |$dr:tt| $decr:expr,
39 |$a:tt| $answer:expr $(,)?
40 ) => {{
41 fn hilbert_curve_order(mut x: usize, mut y: usize, m: usize) -> usize {
42 let n = 1usize << m;
43 let mut ord = 0usize;
44 for k in (0..m).rev() {
45 let rx = x >> k & 1;
46 let ry = y >> k & 1;
47 ord += (1 << k * 2) * (3 * rx ^ ry);
48 if ry == 0 {
49 if rx == 1 {
50 x = n - x - 1;
51 y = n - y - 1;
52 }
53 ::std::mem::swap(&mut x, &mut y);
54 }
55 }
56 ord
57 }
58 let lr: &[(usize, usize)] = $lr;
59 let q = lr.len();
60 let maxv = lr.iter().map(|&(l, r)| l.max(r)).max().unwrap_or_default();
61 let mut m = 0usize;
62 while maxv >= 1 << m {
63 m += 1;
64 }
65 let mut idx: Vec<usize> = (0..q).collect();
66 let ord: Vec<_> = lr
67 .iter()
68 .map(|&(l, r)| hilbert_curve_order(l, r, m))
69 .collect();
70 idx.sort_unstable_by_key(|&i| ord[i]);
71 let (mut $l, mut $r) = (0usize, 0usize);
72 for &$a in idx.iter() {
73 let (nl, nr) = lr[$a];
74 while $l > nl {
75 $l -= 1;
76 let $dl: usize = $l;
77 $decl;
78 }
79 while $r < nr {
80 let $ir: usize = $r;
81 $incr;
82 $r += 1;
83 }
84 while $l < nl {
85 let $il: usize = $l;
86 $incl;
87 $l += 1;
88 }
89 while $r > nr {
90 $r -= 1;
91 let $dr: usize = $r;
92 $decr;
93 }
94 $answer;
95 }
96 }};
97}