pub type UndirectedSparseGraph = SparseGraph<UndirectedEdge>;Aliased Type§
pub struct UndirectedSparseGraph {
vsize: usize,
start: Vec<usize>,
neighbors: Vec<Neighbor<usize, usize>>,
pub edges: Vec<(usize, usize)>,
_marker: PhantomData<fn() -> UndirectedEdge>,
}Fields§
§vsize: usize§start: Vec<usize>§neighbors: Vec<Neighbor<usize, usize>>§edges: Vec<(usize, usize)>§_marker: PhantomData<fn() -> UndirectedEdge>Implementations§
Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcepub fn centroid_decomposition(
&self,
f: impl FnMut(&[usize], &[usize], usize, usize),
)
pub fn centroid_decomposition( &self, f: impl FnMut(&[usize], &[usize], usize, usize), )
1/3 centroid decomposition
Examples found in repository?
crates/competitive/src/tree/distance_frequencies.rs (lines 15-40)
4 pub fn distance_frequencies(&self) -> Vec<u64> {
5 let n = self.vertices_size();
6 let mut table = vec![0u64; n];
7 if n == 0 {
8 return table;
9 }
10 table[0] = n as u64;
11 if n == 1 {
12 return table;
13 }
14 table[1] = (n * 2 - 2) as u64;
15 self.centroid_decomposition(|parents, vs, lsize, _rsize| {
16 let n = vs.len();
17 let mut dist = vec![0usize; n];
18 for i in 1..n {
19 dist[i] = dist[parents[i]] + 1;
20 }
21 let d_max = dist.iter().max().cloned().unwrap_or_default();
22 let mut f = vec![0u64; d_max + 1];
23 let mut g = vec![0u64; d_max + 1];
24 for i in 1..=lsize {
25 f[dist[i]] += 1;
26 }
27 for i in lsize + 1..n {
28 g[dist[i]] += 1;
29 }
30 while f.last().is_some_and(|&x| x == 0) {
31 f.pop();
32 }
33 while g.last().is_some_and(|&x| x == 0) {
34 g.pop();
35 }
36 let h = U64Convolve::convolve(f, g);
37 for (i, &x) in h.iter().enumerate() {
38 table[i] += x * 2;
39 }
40 });
41 table
42 }Sourcepub fn contour_query_range(&self) -> ContourQueryRange
pub fn contour_query_range(&self) -> ContourQueryRange
Examples found in repository?
crates/library_checker/src/tree/vertex_get_range_contour_add_on_tree.rs (line 17)
14pub fn vertex_get_range_contour_add_on_tree(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, mut a: [i64; n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let cq = graph.contour_query_range();
18 let mut bits: Vec<BinaryIndexedTree<AdditiveOperation<_>>> = cq
19 .component_sizes()
20 .map(|n| BinaryIndexedTree::new(n + 1))
21 .collect();
22
23 for _ in 0..q {
24 sc!(query: Query);
25 match query {
26 Query::Add { v, l, r, x } => {
27 cq.for_each_contour_range(v, l, r, |c, start, end| {
28 bits[c].update(start, x);
29 bits[c].update(end, -x);
30 });
31 if l == 0 && 0 < r {
32 a[v] += x;
33 }
34 }
35 Query::Get { v } => {
36 let mut ans = a[v];
37 cq.for_each_index(v, |c, i| ans += bits[c].accumulate(i));
38 pp!(ans);
39 }
40 }
41 }
42}More examples
crates/library_checker/src/tree/vertex_add_range_contour_sum_on_tree.rs (line 17)
14pub fn vertex_add_range_contour_sum_on_tree(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, mut a: [i64; n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let cq = graph.contour_query_range();
18 let mut raw: Vec<_> = cq.component_sizes().map(|n| vec![0; n]).collect();
19 for (v, &x) in a.iter().enumerate() {
20 cq.for_each_index(v, |c, i| raw[c][i] += x);
21 }
22 let mut bits: Vec<BinaryIndexedTree<AdditiveOperation<_>>> = raw
23 .into_iter()
24 .map(|values| BinaryIndexedTree::from_slice(&values))
25 .collect();
26 for _ in 0..q {
27 sc!(query: Query);
28 match query {
29 Query::Add { p, x } => {
30 a[p] += x;
31 cq.for_each_index(p, |c, i| bits[c].update(i, x));
32 }
33 Query::Sum { v, l, r } => {
34 let mut ans = if l == 0 && 0 < r { a[v] } else { 0 };
35 cq.for_each_contour_range(v, l, r, |c, start, end| {
36 ans += bits[c].fold_abelian(start, end);
37 });
38 pp!(ans);
39 }
40 }
41 }
42}Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcefn weighted_depth_dfs<M, F>(
&self,
u: usize,
p: usize,
d: M::T,
depth: &mut Vec<M::T>,
weight: &F,
)
fn weighted_depth_dfs<M, F>( &self, u: usize, p: usize, d: M::T, depth: &mut Vec<M::T>, weight: &F, )
Examples found in repository?
crates/competitive/src/tree/depth.rs (line 34)
21 fn weighted_depth_dfs<M, F>(
22 &self,
23 u: usize,
24 p: usize,
25 d: M::T,
26 depth: &mut Vec<M::T>,
27 weight: &F,
28 ) where
29 M: Monoid,
30 F: Fn(usize) -> M::T,
31 {
32 for a in self.neighbors(u).filter(|a| a.to != p) {
33 let nd = M::operate(&d, &weight(a.label));
34 self.weighted_depth_dfs::<M, _>(a.to, u, nd, depth, weight);
35 }
36 depth[u] = d;
37 }
38 pub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>(
39 &self,
40 root: usize,
41 weight: F,
42 ) -> Vec<M::T> {
43 let mut depth = vec![M::unit(); self.vertices_size()];
44 self.weighted_depth_dfs::<M, _>(root, usize::MAX, M::unit(), &mut depth, &weight);
45 depth
46 }Sourcepub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>(
&self,
root: usize,
weight: F,
) -> Vec<M::T>
pub fn weighted_tree_depth<M: Monoid, F: Fn(usize) -> M::T>( &self, root: usize, weight: F, ) -> Vec<M::T>
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_a.rs (line 8)
5pub fn grl_5_a(reader: impl Read, writer: impl Write) {
6 prepare_io!(reader, writer);
7 sc!(n, (graph, w): @TreeGraphScanner::<usize, u64>::new(n));
8 let d = graph.weighted_tree_depth::<AdditiveOperation<_>, _>(0, |eid| w[eid]);
9 let r = (0..n).max_by_key(|&u| d[u]).unwrap();
10 let ans = graph
11 .weighted_tree_depth::<AdditiveOperation<_>, _>(r, |eid| w[eid])
12 .into_iter()
13 .max()
14 .unwrap();
15 pp!(ans);
16}Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcefn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>)
fn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>)
Examples found in repository?
crates/competitive/src/tree/depth.rs (line 54)
51 fn size_dfs(&self, u: usize, p: usize, size: &mut Vec<u64>) {
52 size[u] = 1;
53 for a in self.neighbors(u).filter(|a| a.to != p) {
54 self.size_dfs(a.to, u, size);
55 size[u] += size[a.to];
56 }
57 }
58 pub fn tree_size(&self, root: usize) -> Vec<u64> {
59 let mut size = vec![0; self.vertices_size()];
60 self.size_dfs(root, usize::MAX, &mut size);
61 size
62 }pub fn tree_size(&self, root: usize) -> Vec<u64>
Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcepub fn distance_frequencies(&self) -> Vec<u64>
pub fn distance_frequencies(&self) -> Vec<u64>
Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
pub fn subtree_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, First>
Sourcepub fn path_euler_tour_builder<'a>(
&'a self,
root: usize,
) -> EulerTourBuilder<'a, FirstLast>
pub fn path_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, FirstLast>
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_d.rs (line 23)
15pub fn grl_5_d(reader: impl Read, writer: impl Write) {
16 prepare_io!(reader, writer);
17 sc!(n, c: [SizedCollect<usize>; iter n]);
18 let edges = c
19 .enumerate()
20 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
21 .collect();
22 let graph = UndirectedSparseGraph::from_edges(n, edges);
23 let et = graph.path_euler_tour_builder(0).build();
24 let mut bit = BinaryIndexedTree::<AdditiveOperation<_>>::new(et.size);
25
26 sc!(q);
27 for _ in 0..q {
28 sc!(query: Query);
29 match query {
30 Query::Add { v, w } => {
31 et.update(v, w, -w, |k, x| bit.update(k, x));
32 }
33 Query::Get { u } => {
34 let ans = et.fold(u, |k| bit.accumulate(k));
35 pp!(ans);
36 }
37 }
38 }
39}pub fn full_euler_tour_builder<'a>( &'a self, root: usize, ) -> EulerTourBuilder<'a, Visit>
Sourcepub fn lca(&self, root: usize) -> LowestCommonAncestor
pub fn lca(&self, root: usize) -> LowestCommonAncestor
Examples found in repository?
crates/aizu_online_judge/src/grl/grl_5_c.rs (line 13)
5pub fn grl_5_c(reader: impl Read, writer: impl Write) {
6 prepare_io!(reader, writer);
7 sc!(n, c: [SizedCollect<usize>; iter n]);
8 let edges = c
9 .enumerate()
10 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
11 .collect();
12 let tree = UndirectedSparseGraph::from_edges(n, edges);
13 let lca = tree.lca(0);
14 sc!(q, uv: [(usize, usize); iter q]);
15 for (u, v) in uv {
16 pp!(lca.lca(u, v));
17 }
18}More examples
crates/library_checker/src/tree/jump_on_tree.rs (line 20)
16pub fn jump_on_tree_level_ancestor(reader: impl Read, writer: impl Write) {
17 prepare_io!(reader, writer);
18 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n));
19 let la = g.level_ancestor(0);
20 let lca = g.lca(0);
21 for _ in 0..q {
22 sc!(s, t, i);
23 let l = lca.lca(s, t);
24 let dl = la.depth(l);
25 let ds = la.depth(s) - dl;
26 let dt = la.depth(t) - dl;
27 let ans = if i <= ds {
28 la.la(s, i)
29 } else if i <= ds + dt {
30 la.la(t, ds + dt - i)
31 } else {
32 None
33 };
34 pp!(ans.unwrap_or(!0) as isize);
35 }
36}
37
38#[verify::library_checker("jump_on_tree")]
39pub fn jump_on_tree_level_ancestor_batch(reader: impl Read, writer: impl Write) {
40 prepare_io!(reader, writer);
41 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n), queries: [(usize, usize, usize); iter q]);
42 let lca = g.lca(0);
43 let results = g.level_ancestor_batch(
44 0,
45 queries.map(|(s, t, i)| {
46 let l = lca.lca(s, t);
47 let dl = lca.depth(l);
48 let ds = lca.depth(s) - dl;
49 let dt = lca.depth(t) - dl;
50 if i <= ds {
51 (s, i)
52 } else if i <= ds + dt {
53 (t, ds + dt - i)
54 } else {
55 (0, n)
56 }
57 }),
58 );
59 pp!(@lf @it results.iter().map(|&v| v.unwrap_or(!0) as isize));
60}Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcepub fn hld(&self, root: usize) -> HeavyLightDecomposition
pub fn hld(&self, root: usize) -> HeavyLightDecomposition
Examples found in repository?
More examples
crates/library_checker/src/tree/vertex_set_path_composite.rs (line 17)
14pub fn vertex_set_path_composite(reader: impl Read, writer: impl Write) {
15 prepare_io!(reader, writer);
16 sc!(n, q, ab: [(M, M); n], (graph, _): @TreeGraphScanner::<usize, ()>::new(n));
17 let hld = graph.hld(0);
18 let mut fold = hld.build_fold::<LinearOperation<_>>(&ab);
19 for _ in 0..q {
20 sc!(query: Query);
21 match query {
22 Query::Set { p, cd } => {
23 fold.set(p, cd);
24 }
25 Query::Apply { u, v, x } => {
26 let (a, b) = fold.fold_vertices(u, v);
27 pp!(a * x + b);
28 }
29 }
30 }
31}crates/library_checker/src/tree/vertex_add_subtree_sum.rs (line 43)
38pub fn vertex_add_subtree_sum_hld(reader: impl Read, writer: impl Write) {
39 prepare_io!(reader, writer);
40 sc!(n, q, a: [u64; n], p: [usize; iter n - 1]);
41 let edges = p.enumerate().map(|(i, p)| (i + 1, p)).collect();
42 let tree = UndirectedSparseGraph::from_edges(n, edges);
43 let hld = tree.hld(0);
44 let mut b = vec![0; n];
45 for (v, x) in a.into_iter().enumerate() {
46 b[hld.index(v)] = x;
47 }
48 let mut seg = SegmentTree::<AdditiveOperation<_>>::from_vec(b);
49 for _ in 0..q {
50 sc!(query: Query);
51 match query {
52 Query::Add { u, x } => seg.update(hld.index(u), x),
53 Query::Sum { u } => {
54 pp!(seg.fold(hld.subtree_range(u)));
55 }
56 }
57 }
58}crates/aizu_online_judge/src/grl/grl_5_e.rs (line 23)
15pub fn grl_5_e(reader: impl Read, writer: impl Write) {
16 prepare_io!(reader, writer);
17 sc!(n, c: [SizedCollect<usize>; iter n]);
18 let edges = c
19 .enumerate()
20 .flat_map(|(u, it)| it.into_iter().map(move |v| (u, v)))
21 .collect();
22 let graph = UndirectedSparseGraph::from_edges(n, edges);
23 let hld = graph.hld(0);
24 let mut seg = LazySegmentTree::<RangeSumRangeAdd<_>>::from_keys(std::iter::repeat_n(0u64, n));
25
26 sc!(q);
27 for _ in 0..q {
28 sc!(query: Query);
29 match query {
30 Query::Add { v, w } => {
31 hld.path_edges(0, v, |l, r| seg.update(l..r, w));
32 }
33 Query::Get { u } => {
34 let mut ans = 0;
35 hld.path_edges(0, u, |l, r| ans += seg.fold(l..r).0);
36 pp!(ans);
37 }
38 }
39 }
40}Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcepub fn level_ancestor(&self, root: usize) -> LevelAncestor
pub fn level_ancestor(&self, root: usize) -> LevelAncestor
Examples found in repository?
crates/library_checker/src/tree/jump_on_tree.rs (line 19)
16pub fn jump_on_tree_level_ancestor(reader: impl Read, writer: impl Write) {
17 prepare_io!(reader, writer);
18 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n));
19 let la = g.level_ancestor(0);
20 let lca = g.lca(0);
21 for _ in 0..q {
22 sc!(s, t, i);
23 let l = lca.lca(s, t);
24 let dl = la.depth(l);
25 let ds = la.depth(s) - dl;
26 let dt = la.depth(t) - dl;
27 let ans = if i <= ds {
28 la.la(s, i)
29 } else if i <= ds + dt {
30 la.la(t, ds + dt - i)
31 } else {
32 None
33 };
34 pp!(ans.unwrap_or(!0) as isize);
35 }
36}More examples
crates/competitive/src/algorithm/doubling.rs (line 278)
183 pub fn new(size: usize, f: impl Fn(usize) -> (usize, M::T)) -> Self {
184 let (next, value): (Vec<_>, Vec<_>) = (0..size).map(f).unzip();
185
186 let mut indeg = vec![0usize; size];
187 for &to in &next {
188 indeg[to] += 1;
189 }
190 let mut in_cycle = vec![true; size];
191 let mut deq = VecDeque::new();
192 for (u, °) in indeg.iter().enumerate() {
193 if deg == 0 {
194 deq.push_back(u);
195 }
196 }
197 while let Some(u) = deq.pop_front() {
198 in_cycle[u] = false;
199 indeg[next[u]] -= 1;
200 if indeg[next[u]] == 0 {
201 deq.push_back(next[u]);
202 }
203 }
204
205 let mut cycle_id = vec![!0; size];
206 let mut cycle_pos = vec![!0; size];
207 let mut cycles = Vec::new();
208 for i in 0..size {
209 if in_cycle[i] && cycle_id[i] == !0 {
210 let mut cycle = Vec::new();
211 let mut u = i;
212 loop {
213 cycle_id[u] = cycles.len();
214 cycle_pos[u] = cycle.len();
215 cycle.push(u);
216 u = next[u];
217 if u == i {
218 break;
219 }
220 }
221 cycles.push(cycle);
222 }
223 }
224
225 let mut rev = vec![Vec::new(); size];
226 for u in 0..size {
227 rev[next[u]].push(u);
228 }
229
230 let mut depth_to_cycle = vec![0usize; size];
231 let mut cycle_entry = vec![!0; size];
232 let mut prefix_up = Vec::with_capacity(size);
233 prefix_up.resize_with(size, M::unit);
234 let mut q = VecDeque::new();
235 for i in 0..size {
236 if in_cycle[i] {
237 cycle_entry[i] = i;
238 prefix_up[i] = M::operate(&value[i], &M::unit());
239 q.push_back(i);
240 }
241 }
242 while let Some(u) = q.pop_front() {
243 for &v in &rev[u] {
244 if in_cycle[v] || cycle_entry[v] != !0 {
245 continue;
246 }
247 cycle_entry[v] = cycle_entry[u];
248 depth_to_cycle[v] = depth_to_cycle[u] + 1;
249 cycle_id[v] = cycle_id[u];
250 prefix_up[v] = M::operate(&value[v], &prefix_up[u]);
251 q.push_back(v);
252 }
253 }
254
255 let mut cycle_prefix = Vec::with_capacity(cycles.len());
256 for cycle in &cycles {
257 let len = cycle.len();
258 let mut pref = Vec::with_capacity(2 * len + 1);
259 pref.push(M::unit());
260 for i in 0..2 * len {
261 let v = cycle[i % len];
262 let next_val = M::operate(pref.last().unwrap(), &value[v]);
263 pref.push(next_val);
264 }
265 cycle_prefix.push(pref);
266 }
267
268 let root = size;
269 let mut edges = Vec::with_capacity(size);
270 for u in 0..size {
271 if in_cycle[u] {
272 edges.push((u, root));
273 } else {
274 edges.push((u, next[u]));
275 }
276 }
277 let graph = UndirectedSparseGraph::from_edges(size + 1, edges);
278 let la = graph.level_ancestor(root);
279
280 Self {
281 depth_to_cycle,
282 cycle_entry,
283 cycle_id,
284 cycle_pos,
285 cycles,
286 cycle_prefix,
287 prefix_up,
288 la,
289 }
290 }Sourcepub fn level_ancestor_batch(
&self,
root: usize,
queries: impl IntoIterator<Item = (usize, usize)>,
) -> Vec<Option<usize>>
pub fn level_ancestor_batch( &self, root: usize, queries: impl IntoIterator<Item = (usize, usize)>, ) -> Vec<Option<usize>>
Examples found in repository?
crates/library_checker/src/tree/jump_on_tree.rs (lines 43-58)
39pub fn jump_on_tree_level_ancestor_batch(reader: impl Read, writer: impl Write) {
40 prepare_io!(reader, writer);
41 sc!(n, q, (g, _): @TreeGraphScanner::<usize>::new(n), queries: [(usize, usize, usize); iter q]);
42 let lca = g.lca(0);
43 let results = g.level_ancestor_batch(
44 0,
45 queries.map(|(s, t, i)| {
46 let l = lca.lca(s, t);
47 let dl = lca.depth(l);
48 let ds = lca.depth(s) - dl;
49 let dt = lca.depth(t) - dl;
50 if i <= ds {
51 (s, i)
52 } else if i <= ds + dt {
53 (t, ds + dt - i)
54 } else {
55 (0, n)
56 }
57 }),
58 );
59 pp!(@lf @it results.iter().map(|&v| v.unwrap_or(!0) as isize));
60}Source§impl UndirectedSparseGraph
impl UndirectedSparseGraph
Sourcepub fn static_top_tree(&self, root: usize) -> StaticTopTree
pub fn static_top_tree(&self, root: usize) -> StaticTopTree
Examples found in repository?
crates/library_checker/src/tree/point_set_tree_path_composite_sum_fixed_root.rs (line 110)
103pub fn point_set_tree_path_composite_sum_fixed_root(reader: impl Read, writer: impl Write) {
104 prepare_io!(reader, writer);
105 sc!(n,
106 q,
107 value: [M; n],
108 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
109
110 let top_tree = graph.static_top_tree(0);
111 let mut dp = top_tree.dp::<Dp>(value, edges);
112
113 for _ in 0..q {
114 sc!(query: Query);
115 match query {
116 Query::SetVertex { v, x } => {
117 dp.set_vertex(v, x);
118 pp!(dp.fold_all().sum);
119 }
120 Query::SetEdge { e, a, b } => {
121 dp.set_edge(e, (a, b));
122 pp!(dp.fold_all().sum);
123 }
124 }
125 }
126}More examples
crates/library_checker/src/tree/point_set_tree_path_composite_sum.rs (line 144)
137pub fn point_set_tree_path_composite_sum(reader: impl Read, writer: impl Write) {
138 prepare_io!(reader, writer);
139 sc!(n,
140 q,
141 value: [M; n],
142 (graph, edges): @TreeGraphScanner::<usize, (M, M)>::new(n));
143
144 let top_tree = graph.static_top_tree(0);
145 let mut dp = top_tree.dp::<Dp>(value, edges);
146
147 for _ in 0..q {
148 sc!(query: Query);
149 match query {
150 Query::SetVertex { v, x, r } => {
151 dp.set_vertex(v, x);
152 pp!(dp.fold_path(r).reverse.sum);
153 }
154 Query::SetEdge { e, a, b, r } => {
155 dp.set_edge(e, (a, b));
156 pp!(dp.fold_path(r).reverse.sum);
157 }
158 }
159 }
160}