Skip to content

Commit 6f26708

Browse files
authored
HLD (#53)
* initial draft; it AC's on LCA * fmt * add some un-tested fns * fmt * add another lca test * refactor * forgot this * progress * add another test * golf * another test * add another test * fmt * nit * clippy * test subtree range with edge values * fmt * clippy * finished refactor * still has bugs * saving progress * nits * now AC's!!!!!!!!!!! * now ACs on yosupo * fix cargo test * finish docs * now works with capturing vars * golf * fix test * reorder * fix * currently WA, but saving progress * now ACs * fix clippy * fix clippy * golf * nit * remove untested function for now * add docs * fix example * fix bug * nit * fix code cov * ok actually fixed code cov this time * fix code cov * simplify test cuz I found a better test * Revert "simplify test cuz I found a better test" This reverts commit 4ab8679. * FIX CODE COV FOR THE LAST TIME!!!!!!!! * refactor * fix clippy * saving progress * fmt * nit * fix test * revert * fix clippy --------- Co-authored-by: Luke Videckis <lukevideckis@gmail.com>
1 parent c2b04a3 commit 6f26708

File tree

13 files changed

+532
-6
lines changed

13 files changed

+532
-6
lines changed

Cargo.toml

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ name = "dijk_yosupo"
5959
path = "examples/graphs/dijk_yosupo.rs"
6060

6161
[[example]]
62-
name = "lca_aizu"
63-
path = "examples/graphs/lca_aizu.rs"
62+
name = "lca_rmq_aizu"
63+
path = "examples/graphs/lca_rmq_aizu.rs"
6464

6565
[[example]]
66-
name = "lca_yosupo"
67-
path = "examples/graphs/lca_yosupo.rs"
66+
name = "lca_rmq_yosupo"
67+
path = "examples/graphs/lca_rmq_yosupo.rs"
6868

6969
[[example]]
7070
name = "scc"
@@ -97,3 +97,31 @@ path = "examples/data_structures/seg_tree_yosupo.rs"
9797
[[example]]
9898
name = "seg_tree_aizu"
9999
path = "examples/data_structures/seg_tree_aizu.rs"
100+
101+
[[example]]
102+
name = "hld_lca_yosupo"
103+
path = "examples/graphs/hld_lca_yosupo.rs"
104+
105+
[[example]]
106+
name = "hld_lca_aizu"
107+
path = "examples/graphs/hld_lca_aizu.rs"
108+
109+
[[example]]
110+
name = "hld_subtree_sum_yosupo"
111+
path = "examples/graphs/hld_subtree_sum_yosupo.rs"
112+
113+
[[example]]
114+
name = "hld_path_sum_yosupo"
115+
path = "examples/graphs/hld_path_sum_yosupo.rs"
116+
117+
[[example]]
118+
name = "hld_path_sum1_aizu"
119+
path = "examples/graphs/hld_path_sum1_aizu.rs"
120+
121+
[[example]]
122+
name = "hld_path_sum2_aizu"
123+
path = "examples/graphs/hld_path_sum2_aizu.rs"
124+
125+
[[example]]
126+
name = "hld_path_composite_yosupo"
127+
path = "examples/graphs/hld_path_composite_yosupo.rs"

examples/graphs/hld_lca_aizu.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// verification-helper: PROBLEM https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C
2+
3+
use proconio::input;
4+
use programming_team_code_rust::graphs::hld::HLD;
5+
6+
fn main() {
7+
input! {
8+
n: usize,
9+
}
10+
11+
let mut adj = (0..n)
12+
.map(|_| {
13+
input! {
14+
k: usize,
15+
c: [usize; k],
16+
}
17+
c
18+
})
19+
.collect::<Vec<Vec<usize>>>();
20+
21+
let hld = HLD::new(&mut adj, true);
22+
23+
input! {
24+
q: usize,
25+
}
26+
27+
for _ in 0..q {
28+
input! {
29+
u: usize,
30+
v: usize,
31+
}
32+
println!("{}", hld.lca(u, v));
33+
}
34+
}

examples/graphs/hld_lca_yosupo.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/lca
2+
3+
use proconio::input;
4+
use programming_team_code_rust::graphs::hld::HLD;
5+
6+
fn main() {
7+
input! {
8+
n: usize,
9+
q: usize,
10+
}
11+
12+
let mut adj = vec![vec![]; n];
13+
for c in 1..n {
14+
input! {
15+
p: usize,
16+
}
17+
adj[c].push(p);
18+
adj[p].push(c);
19+
}
20+
21+
let hld = HLD::new(&mut adj, false);
22+
for _ in 0..q {
23+
input! {
24+
u: usize,
25+
v: usize,
26+
}
27+
println!("{}", hld.lca(u, v));
28+
}
29+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/vertex_set_path_composite
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::seg_tree::SegTree;
5+
use programming_team_code_rust::graphs::hld::HLD;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
q: usize,
11+
}
12+
13+
let a = (0..n)
14+
.map(|_| {
15+
input! {
16+
c: usize,
17+
d: usize
18+
}
19+
(c, d)
20+
})
21+
.collect::<Vec<(usize, usize)>>();
22+
23+
input! {
24+
edges: [(usize, usize); n - 1],
25+
}
26+
27+
let mut adj = vec![vec![]; n];
28+
for &(u, v) in edges.iter() {
29+
adj[u].push(v);
30+
adj[v].push(u);
31+
}
32+
33+
let hld = HLD::new(&mut adj, false);
34+
35+
let mut input_a = vec![(0, 0); n];
36+
for (i, &elem) in a.iter().enumerate() {
37+
input_a[hld.tin[i]] = elem;
38+
}
39+
40+
let mut st_forwards = SegTree::<(usize, usize)>::build_on_array(
41+
&input_a,
42+
move |x, y| (x.0 * y.0 % 998244353, (y.0 * x.1 + y.1) % 998244353),
43+
(1, 0),
44+
);
45+
let mut st_backwards = SegTree::<(usize, usize)>::build_on_array(
46+
&input_a,
47+
move |x, y| (x.0 * y.0 % 998244353, (x.0 * y.1 + x.1) % 998244353),
48+
(1, 0),
49+
);
50+
51+
for _ in 0..q {
52+
input! {
53+
t: usize
54+
}
55+
56+
match t {
57+
0 => {
58+
input! {
59+
u: usize,
60+
c: usize,
61+
d: usize
62+
}
63+
st_forwards.set(hld.tin[u], (c, d));
64+
st_backwards.set(hld.tin[u], (c, d));
65+
}
66+
_ => {
67+
input! {
68+
u: usize,
69+
v: usize,
70+
x: usize
71+
}
72+
let (mut u_anc_val, mut v_anc_val) = (st_forwards.unit, st_backwards.unit);
73+
hld.path(u, v, |range, u_anc| {
74+
if u_anc {
75+
u_anc_val = (st_forwards.op)(&u_anc_val, &st_backwards.query(range));
76+
} else {
77+
v_anc_val = (st_forwards.op)(&st_forwards.query(range), &v_anc_val);
78+
}
79+
});
80+
let res = (st_forwards.op)(&u_anc_val, &v_anc_val);
81+
println!("{}", (res.0 * x + res.1) % 998244353);
82+
}
83+
}
84+
}
85+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// verification-helper: PROBLEM https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_D
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::fenwick::Fenwick;
5+
use programming_team_code_rust::graphs::hld::HLD;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
}
11+
12+
let mut adj = (0..n)
13+
.map(|_| {
14+
input! {
15+
k: usize,
16+
childs: [usize; k],
17+
}
18+
childs
19+
})
20+
.collect::<Vec<Vec<usize>>>();
21+
22+
let hld = HLD::new(&mut adj, true);
23+
let mut fenwick = Fenwick::<usize>::new(n);
24+
25+
input! {
26+
q: usize,
27+
}
28+
29+
for _ in 0..q {
30+
input! {
31+
t: usize
32+
}
33+
34+
match t {
35+
0 => {
36+
input! {
37+
u: usize,
38+
delta: usize,
39+
}
40+
hld.path(u, hld.p[u].unwrap(), |range, _| {
41+
assert!(range.len() <= 1);
42+
if range.len() == 1 {
43+
fenwick.add(range.start, delta)
44+
}
45+
});
46+
}
47+
_ => {
48+
input! {
49+
u: usize,
50+
}
51+
let mut sum = 0;
52+
hld.path(u, 0, |range, _| sum += fenwick.sum(range));
53+
println!("{}", sum);
54+
}
55+
}
56+
}
57+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// verification-helper: PROBLEM https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_E
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::lazy_seg_tree::LazySegTree;
5+
use programming_team_code_rust::graphs::hld::HLD;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
}
11+
12+
let mut adj = (0..n)
13+
.map(|_| {
14+
input! {
15+
k: usize,
16+
childs: [usize; k],
17+
}
18+
childs
19+
})
20+
.collect::<Vec<Vec<usize>>>();
21+
22+
let hld = HLD::new(&mut adj, true);
23+
let mut st = LazySegTree::new(n);
24+
25+
input! {
26+
q: usize,
27+
}
28+
29+
for _ in 0..q {
30+
input! {
31+
t: usize
32+
}
33+
34+
match t {
35+
0 => {
36+
input! {
37+
u: usize,
38+
delta: u64,
39+
}
40+
hld.path(u, 0, |range, _| st.update(range, delta));
41+
}
42+
_ => {
43+
input! {
44+
u: usize,
45+
}
46+
let mut sum = 0;
47+
hld.path(u, 0, |range, _| sum += st.query(range));
48+
println!("{}", sum);
49+
}
50+
}
51+
}
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// verification-helper: PROBLEM https://judge.yosupo.jp/problem/vertex_add_path_sum
2+
3+
use proconio::input;
4+
use programming_team_code_rust::data_structures::fenwick::Fenwick;
5+
use programming_team_code_rust::graphs::hld::HLD;
6+
7+
fn main() {
8+
input! {
9+
n: usize,
10+
q: usize,
11+
a: [usize; n],
12+
edges: [(usize, usize); n - 1],
13+
}
14+
15+
let mut adj = vec![vec![]; n];
16+
for &(u, v) in edges.iter() {
17+
adj[u].push(v);
18+
adj[v].push(u);
19+
}
20+
21+
let hld = HLD::new(&mut adj, false);
22+
let mut fenwick = Fenwick::<usize>::new(n);
23+
24+
for (i, &elem) in a.iter().enumerate() {
25+
fenwick.add(hld.tin[i], elem);
26+
}
27+
28+
for _ in 0..q {
29+
input! {
30+
t: usize
31+
}
32+
33+
match t {
34+
0 => {
35+
input! {
36+
u: usize,
37+
delta: usize,
38+
}
39+
fenwick.add(hld.tin[u], delta);
40+
}
41+
_ => {
42+
input! {
43+
u: usize,
44+
v: usize,
45+
}
46+
let mut sum = 0;
47+
hld.path(u, v, |range, _| sum += fenwick.sum(range));
48+
println!("{}", sum);
49+
}
50+
}
51+
}
52+
}

0 commit comments

Comments
 (0)