Submission #55488507


Source Code Expand

use proconio::{input, marker::Usize1};

fn main() {
    input! {
        n: usize,
    }
    let mut lca = tree::LowestCommonAncestor::new(n);
    for _ in 0..n - 1 {
        input! {
            (a, b): (Usize1, Usize1),
        }
        lca.add_edge(a, b, 1);
    }
    lca.build();
    let merge = |a, b| a + b;
    let tab = lca.build_cost_tab(merge, 0);

    input! {
        q: usize,
    }
    for _ in 0..q {
        input! {
            k: usize,
            mut v: [Usize1; k],
        }
        v.sort_by_key(|vi| lca.get_order(*vi));
        let mut ans = 0;
        for i in 0..k - 1 {
            let (u, v) = (v[i], v[i + 1]);
            ans += lca.lca_cost_tab(u, v, merge, 0, &tab);
        }
        ans += lca.lca_cost_tab(v[k - 1], v[0], merge, 0, &tab);
        ans >>= 1;
        println!("{ans}");
    }
}

mod tree {
    use std::mem::swap;

    use num::Num;

    #[derive(Clone, Copy)]
    struct Edge<T: Ord + Copy + Num> {
        from: usize,
        to: usize,
        cost: T,
    }

    #[allow(dead_code)]
    pub struct LowestCommonAncestor<T: Ord + Copy + Num> {
        n: usize,
        logn: usize,
        edges: Vec<Vec<Edge<T>>>,
        depth: Vec<usize>,
        tab: Vec<Vec<Option<usize>>>,
        order: Vec<usize>,
    }

    impl<T: Ord + Copy + Num> LowestCommonAncestor<T> {
        pub fn new(n: usize) -> Self {
            let edges = vec![vec![]; n];
            let depth = vec![0; n];
            let logn = bit_width(n) - 1;
            let tab = vec![vec![None; logn + 1]; n];
            let order = vec![0; n];
            Self {
                n,
                logn,
                edges,
                depth,
                tab,
                order,
            }
        }

        pub fn add_edge(&mut self, from: usize, to: usize, cost: T) {
            self.add_directed_edge(from, to, cost);
            self.add_directed_edge(to, from, cost);
        }

        fn add_directed_edge(&mut self, from: usize, to: usize, cost: T) {
            let edge = Edge { from, to, cost };
            self.edges[from].push(edge);
        }

        pub fn build(&mut self) {
            self.build_depth();
            self.build_tab();
        }

        fn build_depth(&mut self) {
            self.dfs(0, 0, 0, 0);
        }

        fn dfs(&mut self, v: usize, par: usize, depth: usize, mut order: usize) -> usize {
            self.depth[v] = depth;
            self.order[v] = order;

            let m = self.edges[v].len();
            for i in 0..m {
                let edge = self.edges[v][i];
                if edge.to == par {
                    continue;
                }
                order = self.dfs(edge.to, v, depth + 1, order + 1);
            }

            order
        }

        fn build_tab(&mut self) {
            for i in 0..self.n {
                for edge in self.edges[i].iter() {
                    if self.depth[edge.from] < self.depth[edge.to] {
                        continue;
                    }
                    self.tab[edge.from][0] = Some(edge.to);
                }
            }

            for k in 0..self.logn {
                for i in 0..self.n {
                    if let Some(to) = self.tab[i][k] {
                        self.tab[i][k + 1] = self.tab[to][k];
                    }
                }
            }
        }

        pub fn get_order(&self, v: usize) -> usize {
            self.order[v]
        }

        pub fn lca(&self, mut u: usize, mut v: usize) -> usize {
            if self.depth[u] < self.depth[v] {
                swap(&mut u, &mut v);
            }

            let diff = self.depth[u] - self.depth[v];
            for i in 0..=self.logn {
                if ((diff >> i) & 1) == 1 {
                    u = self.tab[u][i].unwrap();
                }
            }

            if u == v {
                return u;
            }

            for i in (0..=self.logn).rev() {
                if self.tab[u][i].is_none() || self.tab[v][i].is_none() {
                    continue;
                }
                if self.tab[u][i] != self.tab[v][i] {
                    u = self.tab[u][i].unwrap();
                    v = self.tab[v][i].unwrap();
                }
            }

            self.tab[u][0].unwrap()
        }

        pub fn build_cost_tab<F: Fn(T, T) -> T>(&self, merge: F, e: T) -> Vec<Vec<T>> {
            let mut tab = vec![vec![e; self.logn + 1]; self.n];

            for i in 0..self.n {
                for edge in self.edges[i].iter() {
                    if self.depth[edge.from] < self.depth[edge.to] {
                        continue;
                    }
                    tab[edge.from][0] = edge.cost;
                }
            }

            for k in 0..self.logn {
                for i in 0..self.n {
                    if let Some(to) = self.tab[i][k] {
                        tab[i][k + 1] = merge(tab[i][k], tab[to][k]);
                    }
                }
            }

            tab
        }

        pub fn lca_cost_tab<F: Fn(T, T) -> T>(
            &self,
            mut u: usize,
            mut v: usize,
            merge: F,
            e: T,
            tab: &Vec<Vec<T>>,
        ) -> T {
            let mut ret = e;

            if self.depth[u] < self.depth[v] {
                swap(&mut u, &mut v);
            }

            let diff = self.depth[u] - self.depth[v];
            for i in 0..=self.logn {
                if ((diff >> i) & 1) == 1 {
                    ret = merge(ret, tab[u][i]);
                    u = self.tab[u][i].unwrap();
                }
            }

            if u == v {
                return ret;
            }

            for i in (0..=self.logn).rev() {
                if self.tab[u][i].is_none() || self.tab[v][i].is_none() {
                    continue;
                }
                if self.tab[u][i] != self.tab[v][i] {
                    ret = merge(ret, tab[u][i]);
                    ret = merge(ret, tab[v][i]);
                    u = self.tab[u][i].unwrap();
                    v = self.tab[v][i].unwrap();
                }
            }

            ret = merge(ret, tab[u][0]);
            ret = merge(ret, tab[v][0]);

            ret
        }
    }

    fn bit_width(x: usize) -> usize {
        x.ilog2() as usize + 1
    }
}

Submission Info

Submission Time
Task 035 - Preserve Connectivity(★7)
User Plan8
Language Rust (rustc 1.70.0)
Score 7
Code Size 6334 Byte
Status AC
Exec Time 439 ms
Memory 65280 KiB

Compile Error

warning: method `lca` is never used
   --> src/main.rs:135:16
    |
60  |     impl<T: Ord + Copy + Num> LowestCommonAncestor<T> {
    |     ------------------------------------------------- method in this implementation
...
135 |         pub fn lca(&self, mut u: usize, mut v: usize) -> usize {
    |                ^^^
    |
    = note: `#[warn(dead_code)]` on by default

Judge Result

Set Name Sample Subtask1 Subtask2 Subtask3 Subtask4
Score / Max Score 0 / 0 2 / 2 1 / 1 1 / 1 3 / 3
Status
AC × 3
AC × 14
AC × 10
AC × 9
AC × 42
Set Name Test Cases
Sample sample_01.txt, sample_02.txt, sample_03.txt
Subtask1 sub1_01.txt, sub1_02.txt, sub1_03.txt, sub1_04.txt, sub1_05.txt, sub1_06.txt, sub1_07.txt, sub1_08.txt, sub1_09.txt, sub1_10.txt, sub1_11.txt, sample_01.txt, sample_02.txt, sample_03.txt
Subtask2 sub2_01.txt, sub2_02.txt, sub2_03.txt, sub2_04.txt, sub2_05.txt, sub2_06.txt, sub2_07.txt, sub2_08.txt, sample_02.txt, sub1_01.txt
Subtask3 sub3_01.txt, sub3_02.txt, sub3_03.txt, sub3_04.txt, sub3_05.txt, sub3_06.txt, sub3_07.txt, sub3_08.txt, sample_03.txt
Subtask4 sample_01.txt, sample_02.txt, sample_03.txt, sub1_01.txt, sub1_02.txt, sub1_03.txt, sub1_04.txt, sub1_05.txt, sub1_06.txt, sub1_07.txt, sub1_08.txt, sub1_09.txt, sub1_10.txt, sub1_11.txt, sub2_01.txt, sub2_02.txt, sub2_03.txt, sub2_04.txt, sub2_05.txt, sub2_06.txt, sub2_07.txt, sub2_08.txt, sub3_01.txt, sub3_02.txt, sub3_03.txt, sub3_04.txt, sub3_05.txt, sub3_06.txt, sub3_07.txt, sub3_08.txt, sub4_01.txt, sub4_02.txt, sub4_03.txt, sub4_04.txt, sub4_05.txt, sub4_06.txt, sub4_07.txt, sub4_08.txt, sub4_09.txt, sub4_10.txt, sub4_11.txt, sub4_12.txt
Case Name Status Exec Time Memory
sample_01.txt AC 1 ms 1948 KiB
sample_02.txt AC 1 ms 1888 KiB
sample_03.txt AC 1 ms 1872 KiB
sub1_01.txt AC 1 ms 1932 KiB
sub1_02.txt AC 1 ms 1948 KiB
sub1_03.txt AC 1 ms 2076 KiB
sub1_04.txt AC 33 ms 5200 KiB
sub1_05.txt AC 29 ms 5380 KiB
sub1_06.txt AC 32 ms 5332 KiB
sub1_07.txt AC 38 ms 5432 KiB
sub1_08.txt AC 34 ms 5424 KiB
sub1_09.txt AC 34 ms 5552 KiB
sub1_10.txt AC 23 ms 5332 KiB
sub1_11.txt AC 31 ms 5548 KiB
sub2_01.txt AC 272 ms 60480 KiB
sub2_02.txt AC 282 ms 60436 KiB
sub2_03.txt AC 277 ms 60404 KiB
sub2_04.txt AC 407 ms 61408 KiB
sub2_05.txt AC 322 ms 60764 KiB
sub2_06.txt AC 405 ms 62236 KiB
sub2_07.txt AC 234 ms 62024 KiB
sub2_08.txt AC 406 ms 63892 KiB
sub3_01.txt AC 249 ms 60388 KiB
sub3_02.txt AC 249 ms 60360 KiB
sub3_03.txt AC 253 ms 60244 KiB
sub3_04.txt AC 403 ms 63320 KiB
sub3_05.txt AC 352 ms 61404 KiB
sub3_06.txt AC 439 ms 61616 KiB
sub3_07.txt AC 201 ms 61952 KiB
sub3_08.txt AC 411 ms 64364 KiB
sub4_01.txt AC 193 ms 60204 KiB
sub4_02.txt AC 189 ms 60316 KiB
sub4_03.txt AC 179 ms 60320 KiB
sub4_04.txt AC 251 ms 60560 KiB
sub4_05.txt AC 208 ms 61064 KiB
sub4_06.txt AC 197 ms 60732 KiB
sub4_07.txt AC 146 ms 61852 KiB
sub4_08.txt AC 149 ms 61920 KiB
sub4_09.txt AC 157 ms 62028 KiB
sub4_10.txt AC 253 ms 65280 KiB
sub4_11.txt AC 203 ms 64140 KiB
sub4_12.txt AC 170 ms 63528 KiB