Skip to content

Commit 41528c4

Browse files
Disjoint rmq (#92)
* start of DJ RMQ * first draft of disjoint rmq * golf * finish docs * Update disjoint_rmq.rs * Update disjoint_rmq.rs * nit * update example * nits --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com> Co-authored-by: Cameron Custer <73217097+cameroncuster@users.noreply.github.com>
1 parent 7f90dc2 commit 41528c4

File tree

4 files changed

+125
-1
lines changed

4 files changed

+125
-1
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ path = "examples/monotonic/count_rects.rs"
216216
name = "cartesian_tree"
217217
path = "examples/monotonic/cartesian_tree.rs"
218218

219+
[[example]]
220+
name = "disjoint_rmq_non_commutative"
221+
path = "examples/data_structures/disjoint_rmq_non_commutative.rs"
222+
219223
[[example]]
220224
name = "lca_rmq_next_on_path"
221-
path = "examples/graphs/lca_rmq_next_on_path.rs"
225+
path = "examples/graphs/lca_rmq_next_on_path.rs"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/queue_operate_all_composite
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::disjoint_rmq::DisjointRMQ;
5+
6+
const MOD: u64 = 998_244_353;
7+
8+
fn main() {
9+
input! {
10+
q: usize,
11+
}
12+
13+
let mut que = Vec::new();
14+
let mut front = 0;
15+
let mut queries = Vec::new();
16+
17+
for _ in 0..q {
18+
input! {
19+
t: u8,
20+
}
21+
match t {
22+
0 => {
23+
input! {
24+
a: u64,
25+
b: u64,
26+
}
27+
que.push((a, b));
28+
}
29+
1 => {
30+
front += 1;
31+
}
32+
_ => {
33+
input! {
34+
x: u64,
35+
}
36+
queries.push((front..que.len(), x));
37+
}
38+
}
39+
}
40+
41+
let d_rmq = DisjointRMQ::new(&que, |&a, &b| (a.0 * b.0 % MOD, (b.0 * a.1 + b.1) % MOD));
42+
43+
for (range, x) in queries {
44+
if range.is_empty() {
45+
println!("{}", x);
46+
} else {
47+
let (slope, y_int) = d_rmq.query(range);
48+
println!("{}", (slope * x + y_int) % MOD);
49+
}
50+
}
51+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//! # Disjoint Range Minimum Query
2+
3+
/// # Example
4+
/// ```
5+
/// use programming_team_code_rust::data_structures::disjoint_rmq::DisjointRMQ;
6+
///
7+
/// let a = [1, 3, 1, 4, 5];
8+
/// // (min, number of mins)
9+
/// let rmq = DisjointRMQ::new(&a.iter().map(|&x| (x, 1)).collect::<Vec<_>>(), |&x, &y| {
10+
/// if x.0 == y.0 {
11+
/// (x.0, x.1 + y.1)
12+
/// } else {
13+
/// std::cmp::min(x, y)
14+
/// }
15+
/// });
16+
/// assert_eq!(rmq.query(0..5), (1, 2));
17+
/// assert_eq!(rmq.query(3..5), (4, 1));
18+
/// assert!(std::panic::catch_unwind(|| rmq.query(1..1)).is_err());
19+
/// ```
20+
pub struct DisjointRMQ<T, F> {
21+
t: Vec<Vec<T>>,
22+
op: F,
23+
}
24+
25+
impl<T: Clone, F: Fn(&T, &T) -> T> DisjointRMQ<T, F> {
26+
/// Create a new Disjoint RMQ instance
27+
///
28+
/// # Complexity (n = a.len())
29+
/// - Time: O(n log n)
30+
/// - Space: O(n log n)
31+
pub fn new(a: &[T], op: F) -> Self {
32+
let mut t = vec![];
33+
let mut len = 1;
34+
while len <= a.len() {
35+
let mut le = 0;
36+
let mut row = a.to_vec();
37+
while le < a.len() {
38+
let mi = (le + len).min(a.len());
39+
let ri = (le + 2 * len).min(a.len());
40+
for i in (le..mi - 1).rev() {
41+
row[i] = op(&row[i], &row[i + 1]);
42+
}
43+
for i in mi + 1..ri {
44+
row[i] = op(&row[i - 1], &row[i]);
45+
}
46+
le += 2 * len;
47+
}
48+
t.push(row);
49+
len *= 2;
50+
}
51+
Self { t, op }
52+
}
53+
54+
/// Query the range [range.start, range.end)
55+
///
56+
/// # Complexity
57+
/// - Time: O(1)
58+
/// - Space: O(1)
59+
pub fn query(&self, range: std::ops::Range<usize>) -> T {
60+
assert!(!range.is_empty());
61+
if range.len() == 1 {
62+
self.t[0][range.start].clone()
63+
} else {
64+
let lg = (range.start ^ (range.end - 1)).ilog2() as usize;
65+
(self.op)(&self.t[lg][range.start], &self.t[lg][range.end - 1])
66+
}
67+
}
68+
}

src/data_structures/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! # Data Structures
22
pub mod binary_trie;
3+
pub mod disjoint_rmq;
34
pub mod fenwick;
45
pub mod lazy_seg_tree;
56
pub mod rmq;

0 commit comments

Comments
 (0)