結果
問題 | No.1494 LCS on Tree |
ユーザー | to-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 |
ソースコード
// 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 } } } ; }