結果

問題 No.1494 LCS on Tree
ユーザー to-omerto-omer
提出日時 2021-04-30 23:18:40
言語 Rust
(1.77.0 + proconio)
結果
AC  
実行時間 293 ms / 2,000 ms
コード長 30,011 bytes
コンパイル時間 15,050 ms
コンパイル使用メモリ 402,824 KB
実行使用メモリ 279,808 KB
最終ジャッジ日時 2024-11-20 15:05:16
合計ジャッジ時間 21,426 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,816 KB
testcase_01 AC 1 ms
6,816 KB
testcase_02 AC 1 ms
6,816 KB
testcase_03 AC 293 ms
275,456 KB
testcase_04 AC 165 ms
100,224 KB
testcase_05 AC 167 ms
99,968 KB
testcase_06 AC 167 ms
100,608 KB
testcase_07 AC 167 ms
99,840 KB
testcase_08 AC 166 ms
99,328 KB
testcase_09 AC 167 ms
99,840 KB
testcase_10 AC 169 ms
102,400 KB
testcase_11 AC 167 ms
99,840 KB
testcase_12 AC 166 ms
100,096 KB
testcase_13 AC 168 ms
99,584 KB
testcase_14 AC 291 ms
279,808 KB
testcase_15 AC 282 ms
258,688 KB
testcase_16 AC 241 ms
193,408 KB
testcase_17 AC 260 ms
224,640 KB
testcase_18 AC 252 ms
211,072 KB
testcase_19 AC 1 ms
6,816 KB
testcase_20 AC 1 ms
6,816 KB
testcase_21 AC 1 ms
6,820 KB
testcase_22 AC 1 ms
6,820 KB
testcase_23 AC 1 ms
6,820 KB
testcase_24 AC 1 ms
6,816 KB
testcase_25 AC 1 ms
6,820 KB
testcase_26 AC 1 ms
6,816 KB
testcase_27 AC 1 ms
6,820 KB
testcase_28 AC 1 ms
6,820 KB
testcase_29 AC 1 ms
6,816 KB
testcase_30 AC 292 ms
275,584 KB
testcase_31 AC 277 ms
248,960 KB
testcase_32 AC 251 ms
204,032 KB
testcase_33 AC 248 ms
198,784 KB
testcase_34 AC 249 ms
198,400 KB
testcase_35 AC 10 ms
7,552 KB
testcase_36 AC 52 ms
31,104 KB
testcase_37 AC 10 ms
8,192 KB
testcase_38 AC 41 ms
26,368 KB
testcase_39 AC 78 ms
46,464 KB
testcase_40 AC 25 ms
17,280 KB
testcase_41 AC 126 ms
74,368 KB
testcase_42 AC 25 ms
17,408 KB
testcase_43 AC 113 ms
67,712 KB
testcase_44 AC 84 ms
50,304 KB
testcase_45 AC 214 ms
158,848 KB
testcase_46 AC 214 ms
158,848 KB
testcase_47 AC 214 ms
158,848 KB
testcase_48 AC 213 ms
158,848 KB
testcase_49 AC 213 ms
158,848 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

// codesnip-guard: main
fn main() {
    #![allow(unused_imports, unused_macros)]
    prepare_io!(_in_buf, scanner, _out);
    macro_rules ! print { ($ ($ arg : tt) *) => (:: std :: write ! (_out , $ ($ arg) *) . expect ("io error")) }
    macro_rules ! println { ($ ($ arg : tt) *) => (:: std :: writeln ! (_out , $ ($ arg) *) . expect ("io error")) }
    scan!(scanner, n, s: Chars, (g, c): {TreeGraphScanner::<Usize1, char>::new(n)});
    let k = s.len();
    let mut ans = 0usize;
    struct X;
    impl_assoc_value!(X, usize);
    X::set(k);
    impl Magma for X {
        type T = Vec<usize>;
        fn operate(x: &Self::T, y: &Self::T) -> Self::T {
            x.iter()
                .zip(y.iter())
                .map(|(x, y)| x.max(y))
                .cloned()
                .collect()
        }
    }
    impl Unital for X {
        fn unit() -> Self::T {
            let k = X::get();
            vec![0usize; k + 1]
        }
    }
    impl Associative for X {}
    let r = ReRooting::<X, _>::new(&g, |dp: &Vec<usize>, _vid: usize, eid: Option<usize>| {
        let mut ndp = dp.clone();
        if let Some(eid) = eid {
            for i in 0..k {
                chmax!(ndp[i + 1], dp[i] + (c[eid] == s[i]) as usize);
                chmax!(ndp[i + 1], ndp[i]);
            }
        }
        ndp
    });
    for i in 0..n {
        ans.chmax(r.dp[i][k]);
    }
    println!("{}", ans);
}
#[macro_export]
macro_rules! prepare_io {
    ($ in_buf : ident , $ scanner : ident , $ out : ident) => {
        use std::io::{stdout, BufWriter, Write as _};
        let $in_buf = read_stdin_all_unchecked();
        let mut $scanner = Scanner::new(&$in_buf);
        let $out = stdout();
        let mut $out = BufWriter::new($out.lock());
    };
}
// codesnip-guard: _echo
pub fn echo<T: std::fmt::Display>(
    mut writer: impl std::io::Write,
    iter: impl IntoIterator<Item = T>,
    sep: impl std::fmt::Display,
) -> std::io::Result<()> {
    let mut iter = iter.into_iter();
    if let Some(item) = iter.next() {
        write!(writer, "{}", item)?;
    }
    for item in iter {
        write!(writer, "{}{}", sep, item)?;
    }
    writeln!(writer)
}
// codesnip-guard: scanner
pub fn read_stdin_all_unchecked() -> String {
    use std::io::Read as _;
    let mut buf = Vec::new();
    std::io::stdin().read_to_end(&mut buf).expect("io error");
    unsafe { String::from_utf8_unchecked(buf) }
}
pub fn read_stdin_line() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("io error");
    s
}
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules ! iter_scan_impls { ($ ($ t : ty) *) => { $ (impl IterScan for $ t { type Output = Self ; # [inline] fn scan <'a , I : Iterator < Item = &'a str >> (iter : & mut I) -> Option < Self > { iter . next () ?. parse ::<$ t > () . ok () } }) * } ; }
    iter_scan_impls ! (char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String);
    macro_rules ! iter_scan_tuple_impl { ($ ($ T : ident) *) => { impl <$ ($ T : IterScan) ,*> IterScan for ($ ($ T ,) *) { type Output = ($ (<$ T as IterScan >:: Output ,) *) ; # [inline] fn scan <'a , It : Iterator < Item = &'a str >> (_iter : & mut It) -> Option < Self :: Output > { Some (($ (<$ T as IterScan >:: scan (_iter) ?,) *)) } } } ; }
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl ! (A B);
    iter_scan_tuple_impl ! (A B C);
    iter_scan_tuple_impl ! (A B C D);
    iter_scan_tuple_impl ! (A B C D E);
    iter_scan_tuple_impl ! (A B C D E F);
    iter_scan_tuple_impl ! (A B C D E F G);
    iter_scan_tuple_impl ! (A B C D E F G H);
    iter_scan_tuple_impl ! (A B C D E F G H I);
    iter_scan_tuple_impl ! (A B C D E F G H I J);
    iter_scan_tuple_impl ! (A B C D E F G H I J K);
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
#[derive(Debug, Copy, Clone)]
pub struct Usize1;
#[derive(Debug, Copy, Clone)]
pub struct CharWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Chars;
#[derive(Debug, Copy, Clone)]
pub struct CharsWithBase(pub char);
#[derive(Debug, Copy, Clone)]
pub struct Collect<T: IterScan, B: std::iter::FromIterator<<T as IterScan>::Output>> {
    size: usize,
    _marker: std::marker::PhantomData<fn() -> (T, B)>,
}
mod marker_impls {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            <usize as IterScan>::scan(iter)?.checked_sub(1)
        }
    }
    impl MarkedIterScan for CharWithBase {
        type Output = usize;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some((<char as IterScan>::scan(iter)? as u8 - self.0 as u8) as usize)
        }
    }
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules ! scan_value { ($ scanner : expr , ($ ($ t : tt) ,*)) => { ($ ($ crate :: scan_value ! ($ scanner , $ t)) ,*) } ; ($ scanner : expr , [$ t : tt ; $ len : expr]) => { (0 ..$ len) . map (| _ | $ crate :: scan_value ! ($ scanner , $ t)) . collect ::< Vec < _ >> () } ; ($ scanner : expr , [$ t : ty ; $ len : expr]) => { $ scanner . scan_vec ::<$ t > ($ len) } ; ($ scanner : expr , [$ t : ty]) => { $ scanner . iter ::<$ t > () } ; ($ scanner : expr , { $ e : expr }) => { $ scanner . mscan ($ e) } ; ($ scanner : expr , $ t : ty) => { $ scanner . scan ::<$ t > () } ; }
#[macro_export]
macro_rules ! scan { ($ scanner : expr) => { } ; ($ scanner : expr ,) => { } ; ($ scanner : expr , mut $ var : tt : $ t : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , $ var : tt : $ t : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; } ; ($ scanner : expr , mut $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt : $ t : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , $ t) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , mut $ var : tt) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , $ var : tt) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; } ; ($ scanner : expr , mut $ var : tt , $ ($ rest : tt) *) => { let mut $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; ($ scanner : expr , $ var : tt , $ ($ rest : tt) *) => { let $ var = $ crate :: scan_value ! ($ scanner , usize) ; scan ! ($ scanner , $ ($ rest) *) } ; }
// codesnip-guard: SparseGraph
pub use sparse_graph::{
    Adjacency, BidirectionalGraphScanner, BidirectionalSparseGraph, DirectedGraphScanner,
    DirectedSparseGraph, SparseGraph, TreeGraphScanner, UndirectedGraphScanner,
    UndirectedSparseGraph,
};
pub mod sparse_graph {
    use super::*;
    use std::{iter, marker::PhantomData, ops, slice};
    type Marker<T> = PhantomData<fn() -> T>;
    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
    pub struct DirectedEdge;
    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
    pub struct UndirectedEdge;
    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
    pub struct BidirectionalEdge;
    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
    pub struct Adjacency {
        pub id: usize,
        pub to: usize,
    }
    impl Adjacency {
        pub fn new(id: usize, to: usize) -> Adjacency {
            Adjacency { id, to }
        }
    }
    /// Static Sparse Graph represented as Compressed Sparse Row.
    #[derive(Debug, Clone)]
    pub struct SparseGraph<D> {
        vsize: usize,
        pub start: Vec<usize>,
        pub elist: Vec<Adjacency>,
        pub edges: Vec<(usize, usize)>,
        _marker: Marker<D>,
    }
    impl<D> SparseGraph<D> {
        /// Return the number of vertices.
        pub fn vertices_size(&self) -> usize {
            self.vsize
        }
        /// Return the number of edges.
        pub fn edges_size(&self) -> usize {
            self.edges.len()
        }
        /// Return an iterator over graph vertices.
        pub fn vertices(&self) -> ops::Range<usize> {
            0..self.vertices_size()
        }
        /// Return a slice of adjacency vertices.
        pub fn adjacencies(&self, v: usize) -> slice::Iter<'_, Adjacency> {
            self.elist[self.start[v]..self.start[v + 1]].iter()
        }
    }
    pub trait SparseGraphConstruction: Sized {
        fn construct_graph(vsize: usize, edges: Vec<(usize, usize)>) -> SparseGraph<Self>;
    }
    impl<D: SparseGraphConstruction> SparseGraph<D> {
        /// Construct graph from edges.
        pub fn from_edges(vsize: usize, edges: Vec<(usize, usize)>) -> Self {
            D::construct_graph(vsize, edges)
        }
    }
    impl SparseGraphConstruction for DirectedEdge {
        fn construct_graph(vsize: usize, edges: Vec<(usize, usize)>) -> SparseGraph<Self> {
            let mut start: Vec<_> = iter::repeat(0).take(vsize + 1).collect();
            let mut elist = Vec::with_capacity(edges.len());
            unsafe { elist.set_len(edges.len()) }
            for (from, _) in edges.iter().cloned() {
                start[from] += 1;
            }
            for i in 1..=vsize {
                start[i] += start[i - 1];
            }
            for (id, (from, to)) in edges.iter().cloned().enumerate() {
                start[from] -= 1;
                elist[start[from]] = Adjacency::new(id, to);
            }
            SparseGraph {
                vsize,
                start,
                elist,
                edges,
                _marker: PhantomData,
            }
        }
    }
    impl SparseGraphConstruction for UndirectedEdge {
        fn construct_graph(vsize: usize, edges: Vec<(usize, usize)>) -> SparseGraph<Self> {
            let mut start: Vec<_> = iter::repeat(0).take(vsize + 1).collect();
            let mut elist = Vec::with_capacity(edges.len() * 2);
            unsafe { elist.set_len(edges.len() * 2) }
            for (from, to) in edges.iter().cloned() {
                start[to] += 1;
                start[from] += 1;
            }
            for i in 1..=vsize {
                start[i] += start[i - 1];
            }
            for (id, (from, to)) in edges.iter().cloned().enumerate() {
                start[from] -= 1;
                elist[start[from]] = Adjacency::new(id, to);
                start[to] -= 1;
                elist[start[to]] = Adjacency::new(id, from);
            }
            SparseGraph {
                vsize,
                start,
                elist,
                edges,
                _marker: PhantomData,
            }
        }
    }
    impl SparseGraphConstruction for BidirectionalEdge {
        fn construct_graph(vsize: usize, edges: Vec<(usize, usize)>) -> SparseGraph<Self> {
            let mut start: Vec<_> = iter::repeat(0).take(vsize + 1).collect();
            let mut elist = Vec::with_capacity(edges.len() * 2);
            unsafe { elist.set_len(edges.len() * 2) }
            for (from, to) in edges.iter().cloned() {
                start[to] += 1;
                start[from] += 1;
            }
            for i in 1..=vsize {
                start[i] += start[i - 1];
            }
            for (id, (from, to)) in edges.iter().cloned().enumerate() {
                start[from] -= 1;
                elist[start[from]] = Adjacency::new(id * 2, to);
                start[to] -= 1;
                elist[start[to]] = Adjacency::new(id * 2 + 1, from);
            }
            SparseGraph {
                vsize,
                start,
                elist,
                edges,
                _marker: PhantomData,
            }
        }
    }
    pub type DirectedSparseGraph = SparseGraph<DirectedEdge>;
    pub type UndirectedSparseGraph = SparseGraph<UndirectedEdge>;
    pub type BidirectionalSparseGraph = SparseGraph<BidirectionalEdge>;
    pub struct SparseGraphScanner<U: IterScan<Output = usize>, T: IterScan, D> {
        vsize: usize,
        esize: usize,
        _marker: Marker<(U, T, D)>,
    }
    impl<U: IterScan<Output = usize>, T: IterScan, D> SparseGraphScanner<U, T, D> {
        pub fn new(vsize: usize, esize: usize) -> Self {
            Self {
                vsize,
                esize,
                _marker: PhantomData,
            }
        }
    }
    impl<U: IterScan<Output = usize>, T: IterScan, D: SparseGraphConstruction> MarkedIterScan
        for SparseGraphScanner<U, T, D>
    {
        type Output = (SparseGraph<D>, Vec<<T as IterScan>::Output>);
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            let mut edges = Vec::with_capacity(self.esize);
            let mut rest = Vec::with_capacity(self.esize);
            for _ in 0..self.esize {
                edges.push((U::scan(iter)?, U::scan(iter)?));
                rest.push(T::scan(iter)?);
            }
            let graph = SparseGraph::from_edges(self.vsize, edges);
            Some((graph, rest))
        }
    }
    pub type DirectedGraphScanner<U, T> = SparseGraphScanner<U, T, DirectedEdge>;
    pub type UndirectedGraphScanner<U, T> = SparseGraphScanner<U, T, UndirectedEdge>;
    pub type BidirectionalGraphScanner<U, T> = SparseGraphScanner<U, T, BidirectionalEdge>;
    pub struct TreeGraphScanner<U: IterScan<Output = usize>, T: IterScan> {
        vsize: usize,
        _marker: Marker<(U, T)>,
    }
    impl<U: IterScan<Output = usize>, T: IterScan> TreeGraphScanner<U, T> {
        pub fn new(vsize: usize) -> Self {
            Self {
                vsize,
                _marker: PhantomData,
            }
        }
    }
    impl<U: IterScan<Output = usize>, T: IterScan> MarkedIterScan for TreeGraphScanner<U, T> {
        type Output = (UndirectedSparseGraph, Vec<<T as IterScan>::Output>);
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            UndirectedGraphScanner::<U, T>::new(self.vsize, self.vsize - 1).mscan(iter)
        }
    }
}
// codesnip-guard: capture
#[macro_export]
macro_rules ! capture { ([$ ($ ca : tt) *] , fn $ name : ident ($ ($ arg : tt) *) -> $ ret : ty $ body : block) => { capture ! ({ } [$ ($ ca) *,] fn $ name ($ ($ arg) *) -> $ ret $ body) } ; ([$ ($ ca : tt) *] , fn $ name : ident ($ ($ arg : tt) *) $ body : block) => { capture ! ({ } [$ ($ ca) *,] fn $ name ($ ($ arg) *) -> () $ body) } ; ({ $ (($ g : ident , $ ga : expr , $ gt : ty)) * } [] fn $ name : ident ($ ($ a : ident : $ at : ty) ,*) -> $ ret : ty $ body : block) => { fn $ name ($ ($ g : $ gt ,) * $ ($ a : $ at ,) *) -> $ ret { # [allow (unused_macros)] macro_rules ! $ name { () => { |$ ($ a) ,*| $ name ($ ($ g ,) * $ ($ a ,) *) } } $ body } # [allow (unused_mut)] let mut $ name = |$ ($ a) ,*| $ name ($ ($ ga ,) * $ ($ a ,) *) ; } ; ({ $ ($ g : tt) * } [] fn $ name : ident ($ ($ a : ident : $ at : ty) ,*,) $ ($ rest : tt) *) => { capture ! ({ $ ($ g) * } [] fn $ name ($ ($ a : $ at) ,*) $ ($ rest) *) } ; ({ $ ($ done : tt) * } [,] $ ($ rest : tt) *) => { capture ! ({ $ ($ done) * } [] $ ($ rest) *) } ; ({ $ ($ done : tt) * } [$ g : ident : & mut $ gt : ty , $ ($ rest : tt) *] $ ($ info : tt) *) => { capture ! ({ $ ($ done) * ($ g , & mut $ g , & mut $ gt) } [$ ($ rest) *] $ ($ info) *) } ; ({ $ ($ done : tt) * } [$ g : ident : &$ gt : ty , $ ($ rest : tt) *] $ ($ info : tt) *) => { capture ! ({ $ ($ done) * ($ g , &$ g , &$ gt) } [$ ($ rest) *] $ ($ info) *) } ; ({ $ ($ done : tt) * } [$ g : ident : $ gt : ty , $ ($ rest : tt) *] $ ($ info : tt) *) => { capture ! ({ $ ($ done) * ($ g , $ g , $ gt) } [$ ($ rest) *] $ ($ info) *) } ; ({ $ ($ done : tt) * } [$ g : ident , $ ($ rest : tt) *] $ ($ info : tt) *) => { capture ! ({ $ ($ done) * ($ g , $ g , usize) } [$ ($ rest) *] $ ($ info) *) } ; }
// codesnip-guard: GetDistinctMut
pub trait GetDistinctMut<I> {
    type Output;
    fn get_distinct_mut(self, index: I) -> Self::Output;
}
impl<'a, T> GetDistinctMut<(usize, usize)> for &'a mut [T] {
    type Output = (&'a mut T, &'a mut T);
    fn get_distinct_mut(self, (i0, i1): (usize, usize)) -> Self::Output {
        assert_ne!(i0, i1);
        assert!(i0 < self.len());
        assert!(i1 < self.len());
        let ptr = self.as_mut_ptr();
        unsafe { (&mut *ptr.add(i0), &mut *ptr.add(i1)) }
    }
}
impl<'a, T> GetDistinctMut<(usize, usize, usize)> for &'a mut [T] {
    type Output = (&'a mut T, &'a mut T, &'a mut T);
    fn get_distinct_mut(self, (i0, i1, i2): (usize, usize, usize)) -> Self::Output {
        assert_ne!(i0, i1);
        assert_ne!(i0, i2);
        assert!(i0 < self.len());
        assert!(i1 < self.len());
        assert!(i2 < self.len());
        let ptr = self.as_mut_ptr();
        unsafe { (&mut *ptr.add(i0), &mut *ptr.add(i1), &mut *ptr.add(i2)) }
    }
}
// codesnip-guard: ord_tools
pub trait PartialOrdExt: Sized {
    fn chmin(&mut self, other: Self);
    fn chmax(&mut self, other: Self);
    fn minmax(self, other: Self) -> (Self, Self);
}
impl<T> PartialOrdExt for T
where
    T: PartialOrd,
{
    #[inline]
    fn chmin(&mut self, other: Self) {
        if *self > other {
            *self = other;
        }
    }
    #[inline]
    fn chmax(&mut self, other: Self) {
        if *self < other {
            *self = other;
        }
    }
    #[inline]
    fn minmax(self, other: Self) -> (Self, Self) {
        if self < other {
            (self, other)
        } else {
            (other, self)
        }
    }
}
#[macro_export]
macro_rules ! min { ($ l : expr) => { $ l } ; ($ l : expr ,) => { $ crate :: min ! ($ l) } ; ($ l : expr , $ r : expr) => { ($ l) . min ($ r) } ; ($ l : expr , $ r : expr ,) => { $ crate :: min ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: min ! ($ crate :: min ! ($ l , $ r) , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! chmin { ($ l : expr) => { } ; ($ l : expr ,) => { } ; ($ l : expr , $ r : expr) => { { let r = $ r ; if $ l > r { $ l = r ; } } } ; ($ l : expr , $ r : expr ,) => { $ crate :: chmin ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: chmin ! ($ l , $ r) ; $ crate :: chmin ! ($ l , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! max { ($ l : expr) => { $ l } ; ($ l : expr ,) => { $ crate :: max ! ($ l) } ; ($ l : expr , $ r : expr) => { ($ l) . max ($ r) } ; ($ l : expr , $ r : expr ,) => { $ crate :: max ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: max ! ($ crate :: max ! ($ l , $ r) , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! chmax { ($ l : expr) => { } ; ($ l : expr ,) => { } ; ($ l : expr , $ r : expr) => { { let r = $ r ; if $ l < r { $ l = r ; } } } ; ($ l : expr , $ r : expr ,) => { $ crate :: chmax ! ($ l , $ r) } ; ($ l : expr , $ r : expr , $ ($ t : tt) *) => { $ crate :: chmax ! ($ l , $ r) ; $ crate :: chmax ! ($ l , $ ($ t) *) } ; }
#[macro_export]
macro_rules ! minmax { ($ ($ t : tt) *) => { ($ crate :: min ! ($ ($ t) *) , $ crate :: max ! ($ ($ t) *)) } ; }
// codesnip-guard: ReRooting
/// dynamic programming on all-rooted trees
///
/// caluculate all subtrees (hanging on the edge) in specific ordering,
/// each subtree calculated in the order of merge and rooting
#[derive(Clone, Debug)]
pub struct ReRooting<'a, M: Monoid, F: Fn(&M::T, usize, Option<usize>) -> M::T> {
    graph: &'a UndirectedSparseGraph,
    /// dp\[v\]: result of v-rooted tree
    pub dp: Vec<M::T>,
    /// ep\[e\]: result of e-subtree, if e >= n then reversed-e-subtree
    pub ep: Vec<M::T>,
    /// rooting(data, vid, (Optional)eid): add root node(vid), result subtree is edge(eid)
    rooting: F,
}
impl<'a, M, F> ReRooting<'a, M, F>
where
    M: Monoid,
    F: Fn(&M::T, usize, Option<usize>) -> M::T,
{
    pub fn new(graph: &'a UndirectedSparseGraph, rooting: F) -> Self {
        let dp = vec![M::unit(); graph.vertices_size()];
        let ep = vec![M::unit(); graph.vertices_size() * 2];
        let mut self_ = Self {
            graph,
            dp,
            ep,
            rooting,
        };
        self_.rerooting();
        self_
    }
    #[inline]
    fn eidx(&self, u: usize, a: &Adjacency) -> usize {
        a.id + self.graph.edges_size() * (u > a.to) as usize
    }
    #[inline]
    fn reidx(&self, u: usize, a: &Adjacency) -> usize {
        a.id + self.graph.edges_size() * (u < a.to) as usize
    }
    #[inline]
    fn merge(&self, x: &M::T, y: &M::T) -> M::T {
        M::operate(x, y)
    }
    #[inline]
    fn add_subroot(&self, x: &M::T, vid: usize, eid: usize) -> M::T {
        (self.rooting)(x, vid, Some(eid))
    }
    #[inline]
    fn add_root(&self, x: &M::T, vid: usize) -> M::T {
        (self.rooting)(x, vid, None)
    }
    fn dfs(&mut self, pa: &Adjacency, p: usize) {
        let u = pa.to;
        let pi = self.eidx(p, pa);
        for a in self.graph.adjacencies(u).filter(|a| a.to != p) {
            let i = self.eidx(u, a);
            self.dfs(a, u);
            self.ep[pi] = self.merge(&self.ep[pi], &self.ep[i]);
        }
        self.ep[pi] = self.add_subroot(&self.ep[pi], u, pa.id);
    }
    fn efs(&mut self, u: usize, p: usize) {
        let m = self.graph.adjacencies(u).len();
        let mut left = vec![M::unit(); m + 1];
        let mut right = vec![M::unit(); m + 1];
        for (k, a) in self.graph.adjacencies(u).enumerate() {
            let i = self.eidx(u, a);
            left[k + 1] = self.merge(&left[k], &self.ep[i]);
        }
        for (k, a) in self.graph.adjacencies(u).enumerate().rev() {
            let i = self.eidx(u, a);
            right[k] = self.merge(&right[k + 1], &self.ep[i]);
        }
        self.dp[u] = self.add_root(&left[m], u);
        for (k, a) in self.graph.adjacencies(u).enumerate() {
            if a.to != p {
                let i = self.reidx(u, a);
                self.ep[i] = self.merge(&left[k], &right[k + 1]);
                self.ep[i] = self.add_subroot(&self.ep[i], u, a.id);
                self.efs(a.to, u);
            }
        }
    }
    fn rerooting(&mut self) {
        for a in self.graph.adjacencies(0) {
            self.dfs(a, 0);
        }
        self.efs(0, std::usize::MAX);
    }
}
// codesnip-guard: algebra
/// binary operaion: $T \circ T \to T$
pub trait Magma {
    /// type of operands: $T$
    type T: Clone;
    /// binary operaion: $\circ$
    fn operate(x: &Self::T, y: &Self::T) -> Self::T;
    #[inline]
    fn reverse_operate(x: &Self::T, y: &Self::T) -> Self::T {
        Self::operate(y, x)
    }
    #[inline]
    fn operate_assign(x: &mut Self::T, y: &Self::T) {
        *x = Self::operate(x, y);
    }
}
/// $\forall a,\forall b,\forall c \in T, (a \circ b) \circ c = a \circ (b \circ c)$
pub trait Associative {}
/// associative binary operation
pub trait SemiGroup: Magma + Associative {}
impl<S: Magma + Associative> SemiGroup for S {}
/// $\exists e \in T, \forall a \in T, e \circ a = a \circ e = e$
pub trait Unital: Magma {
    /// identity element: $e$
    fn unit() -> Self::T;
    #[inline]
    fn is_unit(x: &Self::T) -> bool
    where
        <Self as Magma>::T: PartialEq,
    {
        x == &Self::unit()
    }
    #[inline]
    fn set_unit(x: &mut Self::T) {
        *x = Self::unit();
    }
}
/// associative binary operation and an identity element
pub trait Monoid: SemiGroup + Unital {
    /// binary exponentiation: $x^n = x\circ\ddots\circ x$
    fn pow(mut x: Self::T, mut n: usize) -> Self::T {
        let mut res = Self::unit();
        while n > 0 {
            if n & 1 == 1 {
                res = Self::operate(&res, &x);
            }
            x = Self::operate(&x, &x);
            n >>= 1;
        }
        res
    }
}
impl<M: SemiGroup + Unital> Monoid for M {}
/// $\exists e \in T, \forall a \in T, \exists b,c \in T, b \circ a = a \circ c = e$
pub trait Invertible: Magma {
    /// $a$ where $a \circ x = e$
    fn inverse(x: &Self::T) -> Self::T;
    #[inline]
    fn rinv_operate(x: &Self::T, y: &Self::T) -> Self::T {
        Self::operate(x, &Self::inverse(y))
    }
}
/// associative binary operation and an identity element and inverse elements
pub trait Group: Monoid + Invertible {}
impl<G: Monoid + Invertible> Group for G {}
/// $\forall a,\forall b \in T, a \circ b = b \circ a$
pub trait Commutative {}
/// commutative monoid
pub trait AbelianMonoid: Monoid + Commutative {}
impl<M: Monoid + Commutative> AbelianMonoid for M {}
/// commutative group
pub trait AbelianGroup: Group + Commutative {}
impl<G: Group + Commutative> AbelianGroup for G {}
/// $\forall a \in T, a \circ a = a$
pub trait Idempotent {}
/// idempotent monoid
pub trait IdempotentMonoid: Monoid + Idempotent {}
impl<M: Monoid + Idempotent> IdempotentMonoid for M {}
#[macro_export]
macro_rules ! monoid_fold { ($ m : ty) => { <$ m as Unital >:: unit () } ; ($ m : ty ,) => { <$ m as Unital >:: unit () } ; ($ m : ty , $ f : expr) => { $ f } ; ($ m : ty , $ f : expr , $ ($ ff : expr) ,*) => { <$ m as Magma >:: operate (& ($ f) , & monoid_fold ! ($ m , $ ($ ff) ,*)) } ; }
// codesnip-guard: AssociatedValue
/// Trait for a modifiable value associated with a type.
pub trait AssociatedValue {
    /// Type of value.
    type T: 'static + Clone;
    fn local_key() -> &'static std::thread::LocalKey<std::cell::UnsafeCell<Self::T>>;
    #[inline]
    fn get() -> Self::T {
        Self::with(Clone::clone)
    }
    #[inline]
    fn set(x: Self::T) {
        Self::local_key().with(|cell| unsafe { *cell.get() = x })
    }
    #[inline]
    fn with<F, R>(f: F) -> R
    where
        F: FnOnce(&Self::T) -> R,
    {
        Self::local_key().with(|cell| unsafe { f(&*cell.get()) })
    }
    #[inline]
    fn modify<F, R>(f: F) -> R
    where
        F: FnOnce(&mut Self::T) -> R,
    {
        Self::local_key().with(|cell| unsafe { f(&mut *cell.get()) })
    }
}
/// Implement [`AssociatedValue`].
///
/// # Examples
///
/// ```
/// use competitive::tools::AssociatedValue;
/// struct X;
/// competitive::impl_assoc_value!(X, usize, 1);
/// assert_eq!(X::get(), 1);
/// X::set(10);
/// assert_eq!(X::get(), 10);
/// ```
///
/// init with `Default::default()`
///
/// ```
/// use competitive::tools::AssociatedValue;
/// struct X;
/// competitive::impl_assoc_value!(X, usize);
/// assert_eq!(X::get(), Default::default());
/// ```
#[macro_export]
macro_rules ! impl_assoc_value { ($ name : ident , $ t : ty) => { $ crate :: impl_assoc_value ! ($ name , $ t , Default :: default ()) ; } ; ($ name : ident , $ t : ty , $ e : expr) => { impl AssociatedValue for $ name { type T = $ t ; # [inline] fn local_key () -> &'static :: std :: thread :: LocalKey <:: std :: cell :: UnsafeCell < Self :: T >> { :: std :: thread_local ! (static __LOCAL_KEY : :: std :: cell :: UnsafeCell <$ t > = :: std :: cell :: UnsafeCell :: new ($ e)) ; & __LOCAL_KEY } } } ; }
0