結果

問題 No.1494 LCS on Tree
ユーザー to-omer
提出日時 2021-04-30 23:06:51
言語 Rust
(1.83.0 + proconio)
結果
WA  
実行時間 -
コード長 22,209 bytes
コンパイル時間 12,370 ms
コンパイル使用メモリ 376,996 KB
実行使用メモリ 33,792 KB
最終ジャッジ日時 2024-07-19 02:55:51
合計ジャッジ時間 16,416 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 12 WA * 35
権限があれば一括ダウンロードができます

ソースコード

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, mut s: Chars, (g, c): {TreeGraphScanner::<Usize1, char>::new(n)});
let k = s.len();
let mut ans = 0usize;
for _ in 0..2 {
let mut lcs = vec![vec![0usize; k + 1]; n];
capture!(
[lcs: &mut Vec<Vec<usize>>, s: &[char], c: &[char], k,],
fn dfs(g: &UndirectedSparseGraph, u: usize, p: usize) {
for a in g.adjacencies(u) {
if a.to != p {
let c = c[a.id];
let (dp, ndp) = lcs.get_distinct_mut((u, a.to));
for i in 0..k {
chmax!(ndp[i + 1], dp[i] + (c == s[i]) as usize);
chmax!(ndp[i + 1], ndp[i]);
}
dfs!()(g, a.to, u);
}
}
}
);
dfs(&g, 0, !0);
s.reverse();
chmax!(ans, lcs.iter().map(|l| l[k]).max().unwrap_or_default());
}
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) *)) } ; }
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0