Skip to content

Commit

Permalink
Merge branch 'main' into deque
Browse files Browse the repository at this point in the history
  • Loading branch information
cameroncuster authored Jul 26, 2024
2 parents 23177b2 + e3b286d commit e92e269
Show file tree
Hide file tree
Showing 16 changed files with 499 additions and 90 deletions.
28 changes: 20 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,8 @@ name = "hld_path_composite_yosupo"
path = "examples/graphs/hld_path_composite_yosupo.rs"

[[example]]
name = "hld_jump_on_tree_nodes"
path = "examples/graphs/hld_jump_on_tree_nodes.rs"

[[example]]
name = "hld_jump_on_tree_edges"
path = "examples/graphs/hld_jump_on_tree_edges.rs"
name = "hld_jump_on_path"
path = "examples/graphs/hld_jump_on_path.rs"

[[example]]
name = "hopcroft_karp_yosupo"
Expand Down Expand Up @@ -201,13 +197,25 @@ name = "lis_yosupo"
path = "examples/helpers/lis_yosupo.rs"

[[example]]
name = "lis_pop"
path = "examples/helpers/lis_pop.rs"
name = "lis_handmade"
path = "examples/helpers/lis_handmade.rs"

[[example]]
name = "range_container_aizu"
path = "examples/data_structures/range_container_aizu.rs"

[[example]]
name = "range_container_handmade"
path = "examples/data_structures/range_container_handmade.rs"

[[example]]
name = "mono_st"
path = "examples/monotonic/mono_st.rs"

[[example]]
name = "hld_aux_tree"
path = "examples/graphs/hld_aux_tree.rs"

[[example]]
name = "count_rects"
path = "examples/monotonic/count_rects.rs"
Expand All @@ -231,3 +239,7 @@ path = "examples/data_structures/disjoint_rmq_non_commutative.rs"
[[example]]
name = "lca_rmq_next_on_path"
path = "examples/graphs/lca_rmq_next_on_path.rs"

[[example]]
name = "linear_rmq"
path = "examples/data_structures/linear_rmq.rs"
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- tests are named `[algo].rs`
- use both yosupo and aizu to test whenever possible because bugs have existed on one of the sites but not the other
- when using both sites name the files `[algo]_yosupo.rs` and `[algo]_aizu.rs`
- when there's no problem to test on, test on [hello world](https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/all/ITP1_1_A) and name the files `[algo]_handmade.rs`
- when only testing a specific function or componenet of some algorithm name the file `[algo]_[component].rs`

# Documentation Guidelines
Expand Down
25 changes: 25 additions & 0 deletions examples/data_structures/linear_rmq.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/staticrmq

use proconio::input;
use programming_team_code_rust::data_structures::linear_rmq::LinearRMQ;

fn main() {
input! {
n: usize,
q: usize,
a: [usize; n],
}

let rmq = LinearRMQ::new(&a, |&x, &y| x.lt(&y));
for _ in 0..q {
input! {
le: usize,
ri: usize,
}
let idx_min = rmq.query_idx(le..ri);
assert!((le..ri).contains(&idx_min));
let res = rmq.query(le..ri);
assert_eq!(a[idx_min], *res);
println!("{}", res);
}
}
45 changes: 45 additions & 0 deletions examples/data_structures/range_container_aizu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/DSL_2_D

use proconio::input;
use programming_team_code_rust::data_structures::range_container::RangeContainer;

fn main() {
input! {
n: usize,
q: usize,
}
let mut rc = RangeContainer::default();
let mut to_value = vec![i32::MAX; 2 * n + 2];
rc.insert_range(0..(2 * n + 1) as i32);

for _ in 0..q {
input! {
kind: usize,
}
match kind {
0 => {
input! {
le: i32,
ri: i32,
x: i32,
}
let le = 2 * le;
let ri = 2 * ri;
let save_range = rc.get_range(ri + 2).unwrap();
let save_value = to_value[save_range.start as usize];
rc.remove_range(le - 1..ri + 2);
rc.insert_range(le..ri + 1);
let save_range = rc.get_range(ri + 2).unwrap();
to_value[save_range.start as usize] = save_value;
to_value[le as usize] = x;
}
_ => {
input! {
index: i32,
}
let range_containing = rc.get_range(2 * index).unwrap();
println!("{}", to_value[range_containing.start as usize]);
}
}
}
}
64 changes: 64 additions & 0 deletions examples/data_structures/range_container_handmade.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/all/ITP1_1_A

use programming_team_code_rust::data_structures::range_container::RangeContainer;
use rand::{thread_rng, Rng};
use std::collections::BTreeMap;

fn main() {
let mut rng = thread_rng();
for _ in 0..100 {
let max_n = rng.gen_range(1..100);
let mut vis = vec![false; max_n + 1];
let mut rc = RangeContainer::default();
for _ in 0..100 {
let mut le = rng.gen_range(0..=max_n);
let mut ri = rng.gen_range(0..=max_n);
if le > ri {
(le, ri) = (ri, le);
}
match rng.gen_range(0..2) {
0 => {
rc.insert_range(le as i32..ri as i32);
for elem in vis.iter_mut().take(ri).skip(le) {
*elem = true;
}
}
_ => {
rc.remove_range(le as i32..ri as i32);
for elem in vis.iter_mut().take(ri).skip(le) {
*elem = false;
}
}
}
let mut to_end = vec![None; max_n + 1];
for i in (0..max_n).rev() {
if vis[i] && !vis[i + 1] {
to_end[i] = Some(i + 1);
} else if vis[i] {
to_end[i] = to_end[i + 1];
}
}
let mut naive_mp = BTreeMap::<i32, i32>::new();
let mut start = None;
for i in 0..max_n + 1 {
if vis[i] {
if start.is_none() {
start = Some(i);
}
assert_eq!(
rc.get_range(i as i32).unwrap(),
start.unwrap() as i32..to_end[i].unwrap() as i32
);
} else {
assert_eq!(rc.get_range(i as i32), None);
if let Some(curr_start) = start {
naive_mp.insert(curr_start as i32, i as i32);
}
start = None;
}
}
assert_eq!(rc.mp, naive_mp);
}
}
println!("Hello World");
}
80 changes: 80 additions & 0 deletions examples/graphs/hld_aux_tree.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/problems/GRL_5_B

use proconio::input;
use programming_team_code_rust::graphs::hld::HLD;
use std::collections::VecDeque;

fn main() {
input! {
n: usize,
edges: [(usize, usize, u32); n - 1],
}

let mut adj_weighted = vec![vec![]; n];
let mut adj = vec![vec![]; n];
for &(u, v, w) in &edges {
adj[u].push(v);
adj[v].push(u);
adj_weighted[u].push((v, w));
adj_weighted[v].push((u, w));
}
let adj_weighted = adj_weighted;

let mut dist = vec![0; n];
{
fn dfs(u: usize, p: Option<usize>, adj_weighted: &[Vec<(usize, u32)>], dist: &mut [u32]) {
for &(v, w) in &adj_weighted[u] {
if Some(v) == p {
continue;
}
dist[v] = w + dist[u];
dfs(v, Some(u), adj_weighted, dist);
}
}
dfs(0, None, &adj_weighted, &mut dist);
}
let dist = dist;

let hld = HLD::new(&mut adj, true);

let weighted_dist = |u: usize, v: usize| -> u32 {
let lc = hld.lca(u, v);
dist[u] + dist[v] - 2 * dist[lc]
};

let mut diam_u = 0;
for i in 1..n {
if weighted_dist(0, i) > weighted_dist(0, diam_u) {
diam_u = i;
}
}
let mut diam_v = 0;
for i in 1..n {
if weighted_dist(diam_u, i) > weighted_dist(diam_u, diam_v) {
diam_v = i;
}
}

for u in 0..n {
let (par, to_node) = hld.aux_tree(vec![diam_u, diam_v, u]);
let mut aux_adj = vec![vec![]; par.len()];
for i in 1..par.len() {
let edge_w = dist[to_node[i]] - dist[to_node[par[i]]];
aux_adj[i].push((par[i], edge_w));
aux_adj[par[i]].push((i, edge_w));
}
let mut q = VecDeque::new();
q.push_back((to_node.iter().position(|&x| x == u).unwrap(), None, 0));
let mut res = 0;
while let Some((node, parent, curr_dist)) = q.pop_front() {
res = res.max(curr_dist);
for &(v, w) in &aux_adj[node] {
if Some(v) == parent {
continue;
}
q.push_back((v, Some(node), curr_dist + w));
}
}
println!("{}", res);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ fn main() {
k: usize,
}

assert_eq!(hld.kth_par(u, hld.d[u]), Some(0));
assert_eq!(hld.kth_par(u, hld.d[u] + 1), None);

match hld.kth_on_path(u, v, k) {
Some(w) => {
assert!(k <= hld.dist(u, v));
Expand Down
59 changes: 0 additions & 59 deletions examples/graphs/hld_jump_on_tree_nodes.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// verification-helper: PROBLEM https://onlinejudge.u-aizu.ac.jp/courses/lesson/2/ITP1/all/ITP1_1_A

use programming_team_code_rust::helpers::lis::Lis;
use rand::{thread_rng, Rng};

fn lis_quadratic(a: &[i32]) -> usize {
let n = a.len();
Expand All @@ -19,13 +20,14 @@ fn lis_quadratic(a: &[i32]) -> usize {
}

fn main() {
let mut rng = thread_rng();
for _ in 0..100 {
let mut lis = Lis::default();
let mut a = Vec::new();
for _ in 0..1000 {
match rand::random::<u8>() % 3 {
match rng.gen_range(0..3) {
0 => {
let new_num = rand::random::<i32>();
let new_num = rng.r#gen();
lis.push(new_num);
a.push(new_num);
}
Expand Down
Loading

0 comments on commit e92e269

Please sign in to comment.