結果

問題 No.901 K-ary εxtrεεmε
ユーザー HaarHaar
提出日時 2024-10-14 20:07:30
言語 Rust
(1.77.0 + proconio)
結果
AC  
実行時間 280 ms / 3,000 ms
コード長 27,504 bytes
コンパイル時間 15,192 ms
コンパイル使用メモリ 379,516 KB
実行使用メモリ 51,844 KB
最終ジャッジ日時 2024-10-14 20:07:58
合計ジャッジ時間 22,307 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 81 ms
51,844 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 2 ms
5,248 KB
testcase_07 AC 268 ms
46,784 KB
testcase_08 AC 221 ms
46,640 KB
testcase_09 AC 205 ms
46,768 KB
testcase_10 AC 207 ms
46,772 KB
testcase_11 AC 197 ms
46,740 KB
testcase_12 AC 216 ms
46,756 KB
testcase_13 AC 192 ms
46,760 KB
testcase_14 AC 195 ms
46,880 KB
testcase_15 AC 199 ms
46,760 KB
testcase_16 AC 193 ms
46,880 KB
testcase_17 AC 205 ms
46,856 KB
testcase_18 AC 232 ms
46,640 KB
testcase_19 AC 217 ms
46,836 KB
testcase_20 AC 198 ms
46,852 KB
testcase_21 AC 198 ms
46,856 KB
testcase_22 AC 176 ms
46,756 KB
testcase_23 AC 191 ms
46,744 KB
testcase_24 AC 280 ms
46,756 KB
testcase_25 AC 194 ms
46,756 KB
testcase_26 AC 188 ms
46,756 KB
testcase_27 AC 145 ms
46,944 KB
testcase_28 AC 152 ms
46,936 KB
testcase_29 AC 151 ms
46,948 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: field `size` is never read
   --> src/main.rs:382:13
    |
381 |         pub struct HLD {
    |                    --- field in this struct
382 |             size: usize,
    |             ^^^^
    |
    = note: `HLD` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
    = note: `#[warn(dead_code)]` on by default

ソースコード

diff #

// Bundled at 2024/10/14 20:05:11 +09:00
// Author: Haar

pub mod main {
    use super::*;
    use haar_lib::algebra::sum::*;
    use haar_lib::ds::segtree::*;
    use haar_lib::tree::{auxiliary_tree::*, hld::*, *};
    #[allow(unused_imports)]
    use haar_lib::{get, input, iter::join_str::*, utils::fastio::*};
    #[allow(unused_imports)]
    use std::cell::{Cell, RefCell};
    #[allow(unused_imports)]
    use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet};
    #[allow(unused_imports)]
    use std::io::Write;
    #[allow(unused_imports)]
    use std::rc::Rc;
    #[derive(Clone, Default)]
    pub struct Problem {}
    impl Problem {
        pub fn main(&mut self) -> Result<(), Box<dyn std::error::Error>> {
            let mut io = FastIO::new();
            let n = io.read_usize();
            let mut builder = TreeBuilder::new(n);
            for _ in 0..n - 1 {
                let u = io.read_usize();
                let v = io.read_usize();
                let w = io.read_u64();
                builder.extend(Some(TreeEdge::new(u, v, w, ())));
            }
            let tree = builder.build();
            let monoid = Sum::<u64>::new();
            let aux = AuxiliaryTree::new(&tree, 0);
            let hld = HLD::new(tree.clone(), 0);
            let mut seg = Segtree::new(n, monoid);
            for e in tree.nodes_iter().flat_map(|a| a.neighbors()) {
                if e.from() < e.to() {
                    seg.update(hld.get_edge_id(e.from(), e.to()).unwrap(), e.weight());
                }
            }
            let q = io.read_usize();
            for _ in 0..q {
                let k = io.read_usize();
                let x = get!(io, [usize; k]);
                let x = aux.build(x, |a, b| hld.lca(a, b));
                let k = x.len();
                let mut ans = 0;
                for i in 0..k {
                    for (l, r) in hld.path_query_edge(x[i], x[(i + 1) % k]) {
                        ans += seg.fold(l..r);
                    }
                }
                ans /= 2;
                io.writeln(ans);
            }
            Ok(())
        }
    }
}
fn main() {
    main::Problem::default().main().unwrap();
}
use crate as haar_lib;
pub mod algebra {
    pub mod traits {
        pub trait AlgeStruct {
            type Output;
        }
        pub trait BinaryOp: AlgeStruct {
            fn op(&self, _: Self::Output, _: Self::Output) -> Self::Output;
        }
        pub trait Identity: AlgeStruct {
            fn id(&self) -> Self::Output;
        }
        pub trait Inverse: AlgeStruct {
            fn inv(&self, _: Self::Output) -> Self::Output;
        }
        pub trait Commutative {}
        pub trait Associative {}
        pub trait Idempotence {}
        pub trait Semigroup: BinaryOp + Associative {}
        impl<T: BinaryOp + Associative> Semigroup for T {}
        pub trait Monoid: Semigroup + Identity {}
        impl<T: Semigroup + Identity> Monoid for T {}
        pub trait AbelianMonoid: Monoid + Commutative {}
        impl<T: Monoid + Commutative> AbelianMonoid for T {}
        pub trait Group: Monoid + Inverse {}
        impl<T: Monoid + Inverse> Group for T {}
        pub trait AbelianGroup: Group + Commutative {}
        impl<T: Group + Commutative> AbelianGroup for T {}
        pub trait Times<T: Clone>: BinaryOp<Output = T> + Identity {
            fn times(&self, mut a: Self::Output, mut n: u64) -> Self::Output {
                let mut ret = self.id();
                while n > 0 {
                    if n & 1 == 1 {
                        ret = self.op(ret, a.clone());
                    }
                    a = self.op(a.clone(), a);
                    n >>= 1;
                }
                ret
            }
        }
        impl<T: Clone, A: BinaryOp<Output = T> + Identity> Times<T> for A {}
    }
    pub mod sum {
        pub use crate::algebra::traits::*;
        use crate::impl_algebra;
        use std::marker::PhantomData;
        #[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
        pub struct Sum<T>(PhantomData<T>);
        impl<T> Sum<T> {
            pub fn new() -> Self {
                Self(PhantomData)
            }
        }
        impl<T> AlgeStruct for Sum<T> {
            type Output = T;
        }
        impl_algebra!(Sum<i8>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: i8| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<i16>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: i16| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<i32>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: i32| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<i64>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: i64| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<i128>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: i128| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<isize>, op: |_, a, b| a + b, id: |_| 0, inv: |_, a: isize| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<u8>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<u16>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<u32>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<u64>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<u128>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<usize>, op: |_, a, b| a + b, id: |_| 0, commu: {}, assoc: {});
        impl_algebra!(Sum<f32>, op: |_, a, b| a + b, id: |_| 0.0, inv: |_, a: f32| -a, commu: {}, assoc: {});
        impl_algebra!(Sum<f64>, op: |_, a, b| a + b, id: |_| 0.0, inv: |_, a: f64| -a, commu: {}, assoc: {});
    }
}
pub mod ds {
    pub mod segtree {
        pub use crate::algebra::traits::Monoid;
        use crate::utils::range::range_bounds_to_range;
        use std::ops::{Index, RangeBounds};
        #[derive(Clone)]
        pub struct Segtree<M: Monoid> {
            original_size: usize,
            size: usize,
            data: Vec<M::Output>,
            monoid: M,
        }
        impl<T: Clone, M: Monoid<Output = T>> Segtree<M> {
            pub fn new(n: usize, monoid: M) -> Self {
                let size = n.next_power_of_two() * 2;
                Segtree {
                    original_size: n,
                    size,
                    data: vec![monoid.id(); size],
                    monoid,
                }
            }
            pub fn fold<R: RangeBounds<usize>>(&self, range: R) -> T {
                let (l, r) = range_bounds_to_range(range, 0, self.size / 2);
                let mut ret_l = self.monoid.id();
                let mut ret_r = self.monoid.id();
                let mut l = l + self.size / 2;
                let mut r = r + self.size / 2;
                while l < r {
                    if r & 1 == 1 {
                        r -= 1;
                        ret_r = self.monoid.op(self.data[r].clone(), ret_r);
                    }
                    if l & 1 == 1 {
                        ret_l = self.monoid.op(ret_l, self.data[l].clone());
                        l += 1;
                    }
                    r >>= 1;
                    l >>= 1;
                }
                self.monoid.op(ret_l, ret_r)
            }
            pub fn assign(&mut self, i: usize, value: T) {
                let mut i = i + self.size / 2;
                self.data[i] = value;
                while i > 1 {
                    i >>= 1;
                    self.data[i] = self
                        .monoid
                        .op(self.data[i << 1].clone(), self.data[i << 1 | 1].clone());
                }
            }
            pub fn update(&mut self, i: usize, value: T) {
                self.assign(
                    i,
                    self.monoid.op(self.data[i + self.size / 2].clone(), value),
                );
            }
        }
        impl<T: Clone, M: Monoid<Output = T>> From<&Segtree<M>> for Vec<T> {
            fn from(from: &Segtree<M>) -> Vec<T> {
                from.data[from.size / 2..from.size / 2 + from.original_size].to_vec()
            }
        }
        impl<M: Monoid> Index<usize> for Segtree<M> {
            type Output = M::Output;
            fn index(&self, i: usize) -> &Self::Output {
                &self.data[self.size / 2 + i]
            }
        }
    }
}
pub mod iter {
    pub mod join_str {
        pub trait JoinStr: Iterator {
            fn join_str(self, s: &str) -> String
            where
                Self: Sized,
                Self::Item: ToString,
            {
                self.map(|x| x.to_string()).collect::<Vec<_>>().join(s)
            }
        }
        impl<I> JoinStr for I where I: Iterator + ?Sized {}
    }
}
pub mod macros {
    pub mod impl_algebra {
        #[macro_export]
        macro_rules! impl_algebra {
    (@bound $t:ty, op: $f:expr; $($bound:tt)+) => {
        impl <$($bound)+> BinaryOp for $t {
            fn op(&self, a: Self::Output, b: Self::Output) -> Self::Output {
                $f(&self, a, b)
            }
        }
    };
    (@nobound $t:ty, op: $f:expr) => {
        impl BinaryOp for $t {
            fn op(&self, a: Self::Output, b: Self::Output) -> Self::Output {
                $f(&self, a, b)
            }
        }
    };
    (@bound $t:ty, id: $f:expr; $($bound:tt)+) => {
        impl<$($bound)+> Identity for $t {
            fn id(&self) -> Self::Output {
                $f(&self)
            }
        }
    };
    (@nobound $t:ty, id: $f:expr) => {
        impl Identity for $t {
            fn id(&self) -> Self::Output {
                $f(&self)
            }
        }
    };
    (@bound $t:ty, inv: $f:expr; $($bound:tt)+) => {
        impl<$($bound)+> Inverse for $t {
            fn inv(&self, a: Self::Output) -> Self::Output {
                $f(self, a)
            }
        }
    };
    (@nobound $t:ty, inv: $f:expr) => {
        impl Inverse for $t {
            fn inv(&self, a: Self::Output) -> Self::Output {
                $f(self, a)
            }
        }
    };
    (@bound $t:ty, commu: $f:expr; $($bound:tt)+) => {impl<$($bound)+> Commutative for $t {}};
    (@nobound $t:ty, commu: $f:expr) => {impl Commutative for $t {}};
    (@bound $t:ty, assoc: $f:expr; $($bound:tt)+) => {impl<$($bound)+> Associative for $t {}};
    (@nobound $t:ty, assoc: $f:expr) => {impl Associative for $t {}};
    (@bound $t:ty, idem: $f:expr; $($bound:tt)+) => {impl<$($bound)+> Idempotence for $t {}};
    (@nobound $t:ty, idem: $f:expr) => {impl Idempotence for $t {}};
    (const $a:ident : $b:ty; $t:ty, $($s:ident: $f:expr),+) => {
        $(impl_algebra!(@bound $t, $s: $f; const $a: $b);)+
    };
    ($a:ident; $t:ty, $($s:ident: $f:expr),+) => {
        $(impl_algebra!(@bound $t, $s: $f; $a);)+
    };
    ($t:ty, $($s:ident: $f:expr),+) => {
        $(impl_algebra!(@nobound $t, $s: $f);)+
    };
}
    }
    pub mod io {
        #[macro_export]
        macro_rules! get {
    ( $in:ident, [$a:tt $(as $to:ty)*; $num:expr] ) => {
        {
            let n = $num;
            (0 .. n).map(|_| get!($in, $a $(as $to)*)).collect::<Vec<_>>()
        }
    };
    ( $in:ident, ($($type:tt $(as $to:ty)*),*) ) => {
        ($(get!($in, $type $(as $to)*)),*)
    };
    ( $in:ident, i8 ) => { $in.read_i64() as i8 };
    ( $in:ident, i16 ) => { $in.read_i64() as i16 };
    ( $in:ident, i32 ) => { $in.read_i64() as i32 };
    ( $in:ident, i64 ) => { $in.read_i64() };
    ( $in:ident, isize ) => { $in.read_i64() as isize };
    ( $in:ident, u8 ) => { $in.read_u64() as u8 };
    ( $in:ident, u16 ) => { $in.read_u64() as u16 };
    ( $in:ident, u32 ) => { $in.read_u64() as u32 };
    ( $in:ident, u64 ) => { $in.read_u64() };
    ( $in:ident, usize ) => { $in.read_u64() as usize };
    ( $in:ident, [char] ) => { $in.read_chars() };
    ( $in:ident, $from:tt as $to:ty ) => { <$to>::from(get!($in, $from)) };
}
        #[macro_export]
        macro_rules! input {
    ( @inner $in:ident, mut $name:ident : $type:tt ) => {
        let mut $name = get!($in, $type);
    };
    ( @inner $in:ident, mut $name:ident : $type:tt as $to:ty ) => {
        let mut $name = get!($in, $type as $to);
    };
    ( @inner $in:ident, $name:ident : $type:tt ) => {
        let $name = get!($in, $type);
    };
    ( @inner $in:ident, $name:ident : $type:tt as $to:ty ) => {
        let $name = get!($in, $type as $to);
    };
    ( $in:ident >> $($($names:ident)* : $type:tt $(as $to:ty)*),* ) => {
        $(input!(@inner $in, $($names)* : $type $(as $to)*);)*
    }
}
    }
}
pub mod tree {
    pub mod auxiliary_tree {
        use crate::tree::*;
        pub struct AuxiliaryTree {
            preorder: Vec<usize>,
        }
        impl AuxiliaryTree {
            pub fn new<E: TreeEdgeTrait>(tree: &Tree<E>, root: usize) -> Self {
                let n = tree.len();
                let mut this = Self {
                    preorder: vec![0; n],
                };
                this.dfs(&tree, root, None, &mut 0);
                this
            }
            fn dfs<E: TreeEdgeTrait>(
                &mut self,
                tree: &Tree<E>,
                cur: usize,
                par: Option<usize>,
                i: &mut usize,
            ) {
                self.preorder[cur] = *i;
                *i += 1;
                for e in tree.nodes[cur].neighbors() {
                    if Some(e.to()) != par {
                        self.dfs(tree, e.to(), Some(cur), i);
                    }
                }
            }
            pub fn build<F>(&self, mut vs: Vec<usize>, f: F) -> Vec<usize>
            where
                F: Fn(usize, usize) -> usize,
            {
                vs.sort_by(|&a, &b| self.preorder[a].cmp(&self.preorder[b]));
                let n = vs.len();
                for i in 0..n - 1 {
                    let x = f(vs[i], vs[i + 1]);
                    vs.push(x);
                }
                vs.sort_by(|&a, &b| self.preorder[a].cmp(&self.preorder[b]));
                vs.dedup();
                vs
            }
        }
    }
    pub mod hld {
        use crate::tree::*;
        use std::cmp::max;
        #[derive(Clone, Debug)]
        pub struct HLD {
            size: usize,
            par: Vec<Option<usize>>,
            head: Vec<usize>,
            id: Vec<usize>,
            rid: Vec<usize>,
            next: Vec<Option<usize>>,
            end: Vec<usize>,
        }
        impl HLD {
            pub fn new<E: TreeEdgeTrait>(tree: Tree<E>, root: usize) -> Self {
                let size = tree.len();
                let mut ret = Self {
                    size,
                    par: vec![None; size],
                    head: vec![0; size],
                    id: vec![0; size],
                    rid: vec![0; size],
                    next: vec![None; size],
                    end: vec![0; size],
                };
                let mut tr = vec![vec![]; size];
                for (i, nodes) in tree.nodes.iter().enumerate() {
                    for e in nodes.neighbors() {
                        tr[i].push(e.to());
                    }
                }
                ret.dfs_sub(&mut tr, root, None, &mut vec![1; size]);
                ret.dfs_build(&tr, root, &mut 0);
                ret
            }
            fn dfs_sub(
                &mut self,
                tree: &mut [Vec<usize>],
                cur: usize,
                par: Option<usize>,
                sub: &mut Vec<usize>,
            ) {
                self.par[cur] = par;
                tree[cur].retain(|&x| Some(x) != par);
                let mut t = 0;
                let n = tree[cur].len();
                for i in 0..n {
                    let to = tree[cur][i];
                    self.dfs_sub(tree, to, Some(cur), sub);
                    sub[cur] += sub[to];
                    if sub[to] > t {
                        t = sub[to];
                        self.next[cur] = Some(to);
                        tree[cur].swap(i, 0);
                    }
                }
            }
            fn dfs_build(&mut self, tree: &[Vec<usize>], cur: usize, index: &mut usize) {
                self.id[cur] = *index;
                self.rid[*index] = cur;
                *index += 1;
                for (i, &to) in tree[cur].iter().enumerate() {
                    self.head[to] = if i == 0 { self.head[cur] } else { to };
                    self.dfs_build(tree, to, index);
                }
                self.end[cur] = *index;
            }
            pub fn path_query_vertex(&self, mut x: usize, mut y: usize) -> Vec<(usize, usize)> {
                let mut ret = vec![];
                loop {
                    if self.id[x] > self.id[y] {
                        std::mem::swap(&mut x, &mut y);
                    }
                    ret.push((max(self.id[self.head[y]], self.id[x]), self.id[y] + 1));
                    if self.head[x] == self.head[y] {
                        break;
                    }
                    y = self.par[self.head[y]].unwrap();
                }
                ret
            }
            pub fn path_query_edge(&self, mut x: usize, mut y: usize) -> Vec<(usize, usize)> {
                let mut ret = vec![];
                loop {
                    if self.id[x] > self.id[y] {
                        std::mem::swap(&mut x, &mut y);
                    }
                    if self.head[x] == self.head[y] {
                        if x != y {
                            ret.push((self.id[x] + 1, self.id[y] + 1));
                        }
                        break;
                    }
                    ret.push((self.id[self.head[y]], self.id[y] + 1));
                    y = self.par[self.head[y]].unwrap();
                }
                ret
            }
            pub fn subtree_query_vertex(&self, x: usize) -> (usize, usize) {
                (self.id[x], self.end[x])
            }
            pub fn subtree_query_edge(&self, x: usize) -> (usize, usize) {
                (self.id[x] + 1, self.end[x])
            }
            pub fn parent(&self, x: usize) -> Option<usize> {
                self.par[x]
            }
            pub fn get_id(&self, x: usize) -> usize {
                self.id[x]
            }
            pub fn get_edge_id(&self, u: usize, v: usize) -> Option<usize> {
                if self.par[u] == Some(v) {
                    Some(self.id[u])
                } else if self.par[v] == Some(u) {
                    Some(self.id[v])
                } else {
                    None
                }
            }
            pub fn lca(&self, mut u: usize, mut v: usize) -> usize {
                loop {
                    if self.id[u] > self.id[v] {
                        std::mem::swap(&mut u, &mut v);
                    }
                    if self.head[u] == self.head[v] {
                        return u;
                    }
                    v = self.par[self.head[v]].unwrap();
                }
            }
        }
    }
    pub trait TreeEdgeTrait {
        type Weight;
        fn from(&self) -> usize;
        fn to(&self) -> usize;
        fn weight(&self) -> Self::Weight;
        fn rev(self) -> Self;
    }
    #[derive(Clone, Debug)]
    pub struct TreeEdge<T, I> {
        pub from: usize,
        pub to: usize,
        pub weight: T,
        pub index: I,
    }
    impl<T, I> TreeEdge<T, I> {
        pub fn new(from: usize, to: usize, weight: T, index: I) -> Self {
            Self {
                from,
                to,
                weight,
                index,
            }
        }
    }
    impl<T: Clone, I> TreeEdgeTrait for TreeEdge<T, I> {
        type Weight = T;
        #[inline]
        fn from(&self) -> usize {
            self.from
        }
        #[inline]
        fn to(&self) -> usize {
            self.to
        }
        #[inline]
        fn weight(&self) -> Self::Weight {
            self.weight.clone()
        }
        fn rev(mut self) -> Self {
            std::mem::swap(&mut self.from, &mut self.to);
            self
        }
    }
    #[derive(Clone, Debug, Default)]
    pub struct TreeNode<E> {
        pub parent: Option<E>,
        pub children: Vec<E>,
    }
    impl<E: TreeEdgeTrait> TreeNode<E> {
        pub fn neighbors(&self) -> impl DoubleEndedIterator<Item = &E> {
            self.children.iter().chain(self.parent.iter())
        }
        pub fn neighbors_size(&self) -> usize {
            self.children.len() + self.parent.as_ref().map_or(0, |_| 1)
        }
    }
    pub struct TreeBuilder<E> {
        nodes: Vec<TreeNode<E>>,
    }
    impl<E: TreeEdgeTrait + Clone> TreeBuilder<E> {
        pub fn new(size: usize) -> Self {
            Self {
                nodes: vec![
                    TreeNode {
                        parent: None,
                        children: vec![],
                    };
                    size
                ],
            }
        }
        pub fn extend(&mut self, edges: impl IntoIterator<Item = E>) {
            for e in edges {
                self.nodes[e.from()].children.push(e.clone());
                self.nodes[e.to()].children.push(e.rev());
            }
        }
        pub fn build(self) -> Tree<E> {
            Tree {
                nodes: self.nodes,
                root: None,
            }
        }
    }
    pub struct RootedTreeBuilder<E> {
        nodes: Vec<TreeNode<E>>,
        root: usize,
    }
    impl<E: TreeEdgeTrait + Clone> RootedTreeBuilder<E> {
        pub fn new(size: usize, root: usize) -> Self {
            Self {
                nodes: vec![
                    TreeNode {
                        parent: None,
                        children: vec![],
                    };
                    size
                ],
                root,
            }
        }
        pub fn extend(&mut self, edges: impl IntoIterator<Item = E>) {
            for e in edges {
                assert!(self.nodes[e.to()].parent.is_none());
                self.nodes[e.from()].children.push(e.clone());
                self.nodes[e.to()].parent.replace(e.rev());
            }
        }
        pub fn build(self) -> Tree<E> {
            Tree {
                nodes: self.nodes,
                root: Some(self.root),
            }
        }
    }
    #[derive(Clone, Debug)]
    pub struct Tree<E> {
        nodes: Vec<TreeNode<E>>,
        root: Option<usize>,
    }
    impl<E> Tree<E> {
        pub fn nodes_iter(&self) -> impl Iterator<Item = &TreeNode<E>> {
            self.nodes.iter()
        }
        pub fn nodes(&self, i: usize) -> &TreeNode<E> {
            &self.nodes[i]
        }
        pub fn len(&self) -> usize {
            self.nodes.len()
        }
        pub fn is_empty(&self) -> bool {
            self.nodes.is_empty()
        }
        pub fn root(&self) -> Option<usize> {
            self.root
        }
    }
}
pub mod utils {
    pub mod fastio {
        use std::fmt::Display;
        use std::io::{Read, Write};
        pub struct FastIO {
            in_bytes: Vec<u8>,
            in_cur: usize,
            out_buf: std::io::BufWriter<std::io::Stdout>,
        }
        impl FastIO {
            pub fn new() -> Self {
                let mut s = vec![];
                std::io::stdin().read_to_end(&mut s).unwrap();
                let cout = std::io::stdout();
                Self {
                    in_bytes: s,
                    in_cur: 0,
                    out_buf: std::io::BufWriter::new(cout),
                }
            }
            #[inline]
            pub fn getc(&mut self) -> Option<u8> {
                if self.in_cur < self.in_bytes.len() {
                    self.in_cur += 1;
                    Some(self.in_bytes[self.in_cur])
                } else {
                    None
                }
            }
            #[inline]
            pub fn peek(&self) -> Option<u8> {
                if self.in_cur < self.in_bytes.len() {
                    Some(self.in_bytes[self.in_cur])
                } else {
                    None
                }
            }
            #[inline]
            pub fn skip(&mut self) {
                while self.peek().map_or(false, |c| c.is_ascii_whitespace()) {
                    self.in_cur += 1;
                }
            }
            pub fn read_u64(&mut self) -> u64 {
                self.skip();
                let mut ret: u64 = 0;
                while self.peek().map_or(false, |c| c.is_ascii_digit()) {
                    ret = ret * 10 + (self.in_bytes[self.in_cur] - b'0') as u64;
                    self.in_cur += 1;
                }
                ret
            }
            pub fn read_u32(&mut self) -> u32 {
                self.read_u64() as u32
            }
            pub fn read_usize(&mut self) -> usize {
                self.read_u64() as usize
            }
            pub fn read_i64(&mut self) -> i64 {
                self.skip();
                let mut ret: i64 = 0;
                let minus = if self.peek() == Some(b'-') {
                    self.in_cur += 1;
                    true
                } else {
                    false
                };
                while self.peek().map_or(false, |c| c.is_ascii_digit()) {
                    ret = ret * 10 + (self.in_bytes[self.in_cur] - b'0') as i64;
                    self.in_cur += 1;
                }
                if minus {
                    ret = -ret;
                }
                ret
            }
            pub fn read_i32(&mut self) -> i32 {
                self.read_i64() as i32
            }
            pub fn read_isize(&mut self) -> isize {
                self.read_i64() as isize
            }
            pub fn read_f64(&mut self) -> f64 {
                self.read_chars()
                    .into_iter()
                    .collect::<String>()
                    .parse()
                    .unwrap()
            }
            pub fn read_chars(&mut self) -> Vec<char> {
                self.skip();
                let mut ret = vec![];
                while self.peek().map_or(false, |c| c.is_ascii_graphic()) {
                    ret.push(self.in_bytes[self.in_cur] as char);
                    self.in_cur += 1;
                }
                ret
            }
            pub fn write<T: Display>(&mut self, s: T) {
                self.out_buf.write_all(format!("{}", s).as_bytes()).unwrap();
            }
            pub fn writeln<T: Display>(&mut self, s: T) {
                self.write(s);
                self.out_buf.write_all(&[b'\n']).unwrap();
            }
        }
        impl Drop for FastIO {
            fn drop(&mut self) {
                self.out_buf.flush().unwrap();
            }
        }
    }
    pub mod range {
        use std::ops::RangeBounds;
        pub fn range_bounds_to_range<R: RangeBounds<usize>>(
            r: R,
            start: usize,
            end: usize,
        ) -> (usize, usize) {
            use std::ops::Bound::*;
            let l = match r.start_bound() {
                Included(&l) => l,
                Excluded(&l) => l + 1,
                Unbounded => start,
            }
            .max(start);
            let r = match r.end_bound() {
                Included(&r) => r + 1,
                Excluded(&r) => r,
                Unbounded => end,
            }
            .min(end);
            (l, r)
        }
    }
}
 
0