結果

問題 No.899 γatheree
ユーザー HaarHaar
提出日時 2021-12-01 23:32:08
言語 Rust
(1.77.0)
結果
WA  
実行時間 -
コード長 17,995 bytes
コンパイル時間 4,703 ms
コンパイル使用メモリ 153,872 KB
実行使用メモリ 27,672 KB
最終ジャッジ日時 2023-09-18 09:49:14
合計ジャッジ時間 26,990 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,384 KB
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 AC 1 ms
4,376 KB
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 AC 904 ms
27,472 KB
testcase_22 AC 920 ms
27,428 KB
testcase_23 AC 916 ms
27,348 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#![allow(unused_imports)]
use std::io::{Read, Write};

#[allow(unused_macros)]
macro_rules! get {
    ( $in:ident, [$a:tt; $num:expr] ) => {
        {
            let n = $num;
            (0 .. n).map(|_| get!($in, $a)).collect::<Vec<_>>()
        }
    };

    ( $in:ident, ($($type:ty),*) ) => {
        ($(get!($in, $type)),*)
    };

    ( $in:ident, $type:ty ) => {
        {
            let token = $in.next().unwrap();

            token.parse::<$type>().expect(
                format!("cannot convert \"{}\" into {}", token, stringify!($type)).as_str()
            )
        }
    };
}

macro_rules! input {
    ( @inner $in:ident, mut $name:ident : $type:tt ) => {
        let mut $name = get!($in, $type);
    };

    ( @inner $in:ident, $name:ident : $type:tt ) => {
        let $name = get!($in, $type);
    };

    ( $in:ident, $($($names:ident)* : $type:tt),* ) => {
        $(
            input!(@inner $in, $($names)* : $type);
        )*
    }
}

#[allow(unused_macros)]
macro_rules! io {
    ( $in:ident, $out:ident ) => {
        let mut s = String::new();
        std::io::stdin().read_to_string(&mut s).unwrap();
        let mut $in = s.split_ascii_whitespace();

        let $out = std::io::stdout();
        let mut $out = std::io::BufWriter::new($out.lock());
    };
}

pub mod main {
    use super::*;
    use haar_lib::{
        algebra::update_sum::*,
        ds::lazy_segtree::*,
        //chmin, chmax,
        //mul_vec,
        tree::{depth_query::*, *},
    };

    #[derive(Clone, Default)]
    pub struct Problem {/* write variables here */}

    impl Problem {
        pub fn main(&mut self) -> Result<(), Box<dyn std::error::Error>> {
            io!(cin, cout);

            input!(cin, n: usize);

            let mut tree = Tree::new(n);
            for _ in 0..n - 1 {
                input!(cin, u: usize, v: usize);
                tree.add_undirected(vec![(u, v, ())]);
            }

            let res = TreeDepthQuery::new(&tree, 0);

            input!(cin, a: [u64; n]);
            let mut seg = LazySegmentTree::new(n, UpdateSum::<u64, u64>::new());

            for i in 0..n {
                let (l, r) = res.me_query(i);
                seg.update(l..r, Some(a[i]));
            }

            input!(cin, q: usize);
            for _ in 0..q {
                input!(cin, x: usize);

                let mut ans = 0;

                let mut f = |(l, r)| {
                    ans += seg.fold(l..r);
                    seg.update(l..r, Some(0));
                };

                if let Some(x) = res.ancestor(x, 2) {
                    f(res.me_query(x));
                }

                if let Some(x) = res.ancestor(x, 1) {
                    f(res.me_query(x));
                    res.children_query(x, 1).map(|p| f(p));
                }

                f(res.me_query(x));

                res.children_query(x, 1).map(|p| f(p));

                res.children_query(x, 2).map(|p| f(p));

                let (l, r) = res.me_query(x);
                seg.update(l..r, Some(ans));

                writeln!(cout, "{}", ans)?;
            }

            Ok(())
        }
        /* write functions here */
    }
}

fn main() {
    main::Problem::default().main().unwrap();
}
use crate as haar_lib;
pub mod algebra {
    pub mod action {
        pub trait Action {
            type FType;
            type UType;
            fn fold_id(&self) -> Self::FType;
            fn fold(&self, x: Self::FType, y: Self::FType) -> Self::FType;
            fn update_id(&self) -> Self::UType;
            fn update(&self, next: Self::UType, cur: Self::UType) -> Self::UType;
            fn convert(&self, x: Self::FType, y: Self::UType, l: usize) -> Self::FType;
        }
    }

    pub mod update_sum {
        use crate::algebra::action::Action;

        use std::{
            marker::PhantomData,
            ops::{Add, Mul},
        };

        #[derive(Clone, Default)]
        pub struct UpdateSum<T, U>(PhantomData<T>, PhantomData<U>);

        impl<T, U> UpdateSum<T, U> {
            pub fn new() -> Self {
                Self(PhantomData, PhantomData)
            }
        }

        impl<T, U> Action for UpdateSum<T, U>
        where
            T: Add<Output = T> + Default + From<U>,
            U: Mul<Output = U> + Default + From<u64>,
        {
            type FType = T;

            type UType = Option<U>;

            fn fold_id(&self) -> Self::FType {
                T::default()
            }

            fn fold(&self, x: Self::FType, y: Self::FType) -> Self::FType {
                x + y
            }

            fn update_id(&self) -> Self::UType {
                None
            }

            fn update(&self, x: Self::UType, y: Self::UType) -> Self::UType {
                match x {
                    Some(_) => x,
                    _ => y,
                }
            }

            fn convert(&self, x: Self::FType, y: Self::UType, l: usize) -> Self::FType {
                match y {
                    Some(y) => T::from(y * U::from(l as u64)),
                    _ => x,
                }
            }
        }
    }
}
pub mod algo {
    pub mod bsearch {
        #[doc = " x以上となる最小のindexを求める。"]
        #[doc = ""]
        #[doc = " # Complexity"]
        #[doc = " Time complexity $O(\\log(n))$"]
        pub fn lower_bound<T: Ord>(a: &[T], value: &T) -> usize {
            let n = a.len();
            let mut lb = 0;
            let mut len = n;
            while len > 0 {
                let half = len / 2;
                let mid = lb + half;
                if &a[mid] < value {
                    len -= half + 1;
                    lb = mid + 1;
                } else {
                    len = half;
                }
            }
            lb
        }

        #[doc = " xを超える最小のindexを求める。"]
        #[doc = ""]
        #[doc = " # Complexity"]
        #[doc = " Time complexity $O(\\log(n))$"]
        pub fn upper_bound<T: Ord>(a: &[T], value: &T) -> usize {
            let n = a.len();
            let mut ub = 0;
            let mut len = n;
            while len > 0 {
                let half = len / 2;
                let mid = ub + half;
                if &a[mid] <= value {
                    len -= half + 1;
                    ub = mid + 1;
                } else {
                    len = half;
                }
            }
            ub
        }

        #[doc = " lower_bound, upper_boundの組を求める。"]
        #[doc = ""]
        #[doc = " # Complexity"]
        #[doc = " Time complexity $O(\\log(n))$"]
        pub fn equal_range<T: Ord>(a: &[T], value: &T) -> (usize, usize) {
            (lower_bound(a, value), upper_bound(a, value))
        }
    }
}
pub mod ds {
    pub mod traits {
        pub trait Foldable<Idx> {
            type Output;
            fn fold(&self, range: Idx) -> Self::Output;
        }

        pub trait FoldableMut<Idx> {
            type Output;
            fn fold(&mut self, range: Idx) -> Self::Output;
        }

        pub trait Assignable<Idx> {
            type Value;
            fn assign(&mut self, i: Idx, value: Self::Value);
        }

        pub trait Updatable<Idx> {
            type Value;
            fn update(&mut self, i: Idx, value: Self::Value);
        }

        pub trait IndexableMut<Idx> {
            type Output;
            fn get(&mut self, i: Idx) -> Self::Output;
        }
    }

    pub mod lazy_segtree {
        use crate::algebra::action::Action;

        pub use crate::ds::traits::*;

        use std::ops::Range;

        pub struct LazySegmentTree<T, U, A> {
            size: usize,
            data: Vec<T>,
            lazy: Vec<U>,
            action: A,
        }

        impl<T: Clone + Eq, U: Clone + Eq, A: Clone + Action<FType = T, UType = U>>
            LazySegmentTree<T, U, A>
        {
            pub fn new(n: usize, a: A) -> Self {
                let size = n.next_power_of_two() * 2;
                Self {
                    size,
                    data: vec![a.fold_id(); size],
                    lazy: vec![a.update_id(); size],
                    action: a,
                }
            }

            fn propagate(&mut self, i: usize) {
                if self.lazy[i] == self.action.update_id() {
                    return;
                }
                if i < self.size / 2 {
                    self.lazy[i << 1] = self
                        .action
                        .update(self.lazy[i].clone(), self.lazy[i << 1].clone());
                    self.lazy[i << 1 | 1] = self
                        .action
                        .update(self.lazy[i].clone(), self.lazy[i << 1 | 1].clone());
                }
                let len = (self.size / 2) >> (31 - (i as u32).leading_zeros());
                self.data[i] = self
                    .action
                    .convert(self.data[i].clone(), self.lazy[i].clone(), len);
                self.lazy[i] = self.action.update_id();
            }

            fn propagate_top_down(&mut self, mut i: usize) {
                let mut temp = vec![];
                while i > 1 {
                    i >>= 1;
                    temp.push(i);
                }
                for &i in temp.iter().rev() {
                    self.propagate(i);
                }
            }

            fn bottom_up(&mut self, mut i: usize) {
                while i > 1 {
                    i >>= 1;
                    self.propagate(i << 1);
                    self.propagate(i << 1 | 1);
                    self.data[i] = self
                        .action
                        .fold(self.data[i << 1].clone(), self.data[i << 1 | 1].clone());
                }
            }
        }

        impl<T: Clone + Eq, U: Clone + Eq, A: Clone + Action<FType = T, UType = U>>
            Updatable<Range<usize>> for LazySegmentTree<T, U, A>
        {
            type Value = U;

            fn update(&mut self, Range { start: l, end: r }: Range<usize>, x: U) {
                self.propagate_top_down(l + self.size / 2);
                if r < self.size / 2 {
                    self.propagate_top_down(r + self.size / 2);
                }
                {
                    let mut l = l + self.size / 2;
                    let mut r = r + self.size / 2;
                    while l < r {
                        if r & 1 == 1 {
                            r -= 1;
                            self.lazy[r] = self.action.update(x.clone(), self.lazy[r].clone());
                            self.propagate(r);
                        }
                        if l & 1 == 1 {
                            self.lazy[l] = self.action.update(x.clone(), self.lazy[l].clone());
                            self.propagate(l);
                            l += 1;
                        }
                        r >>= 1;
                        l >>= 1;
                    }
                }
                self.bottom_up(l + self.size / 2);
                if r < self.size / 2 {
                    self.bottom_up(r + self.size / 2);
                }
            }
        }

        impl<T: Clone + Eq, U: Clone + Eq, A: Clone + Action<FType = T, UType = U>>
            FoldableMut<Range<usize>> for LazySegmentTree<T, U, A>
        {
            type Output = T;

            fn fold(&mut self, Range { start: l, end: r }: Range<usize>) -> Self::Output {
                self.propagate_top_down(l + self.size / 2);
                if r < self.size / 2 {
                    self.propagate_top_down(r + self.size / 2);
                }
                let mut ret_l = self.action.fold_id();
                let mut ret_r = self.action.fold_id();
                let mut l = l + self.size / 2;
                let mut r = r + self.size / 2;
                while l < r {
                    if r & 1 == 1 {
                        r -= 1;
                        self.propagate(r);
                        ret_r = self.action.fold(self.data[r].clone(), ret_r.clone());
                    }
                    if l & 1 == 1 {
                        self.propagate(l);
                        ret_l = self.action.fold(ret_l.clone(), self.data[l].clone());
                        l += 1;
                    }
                    r >>= 1;
                    l >>= 1;
                }
                self.action.fold(ret_l, ret_r)
            }
        }
    }
}
pub mod tree {
    pub mod depth_query {
        use crate::{algo::bsearch::lower_bound, tree::*};

        use std::collections::VecDeque;

        pub struct TreeDepthQuery {
            par: Vec<Option<usize>>,
            depth: Vec<usize>,
            left: Vec<usize>,
            right: Vec<usize>,
            bfs_ord: Vec<Vec<usize>>,
            dfs_ord: Vec<Vec<usize>>,
            ord: Vec<usize>,
        }

        impl TreeDepthQuery {
            pub fn new<T>(tree: &Tree<T>, root: usize) -> Self {
                let size = tree.len();
                let mut ret = Self {
                    par: vec![None; size],
                    depth: vec![0; size],
                    left: vec![0; size],
                    right: vec![0; size],
                    bfs_ord: vec![],
                    dfs_ord: vec![],
                    ord: vec![0; size],
                };
                ret.dfs(&tree, root, None, 0, &mut 0);
                let mut q = VecDeque::new();
                q.push_back((root, 0));
                let mut ord = 0;
                while let Some((i, d)) = q.pop_front() {
                    if ret.bfs_ord.len() <= d {
                        ret.bfs_ord.push(vec![]);
                    }
                    ret.bfs_ord[d].push(ord);
                    ret.ord[i] = ord;
                    ord += 1;
                    for &TreeEdge { to, .. } in tree.nodes[i].neighbors() {
                        if Some(to) != ret.par[i] {
                            q.push_back((to, d + 1));
                        }
                    }
                }
                ret
            }

            fn dfs<T>(
                &mut self,
                tree: &Tree<T>,
                cur: usize,
                par: Option<usize>,
                d: usize,
                ord: &mut usize,
            ) {
                self.par[cur] = par;
                self.depth[cur] = d;
                if self.dfs_ord.len() <= d {
                    self.dfs_ord.push(vec![]);
                }
                self.dfs_ord[d].push(*ord);
                self.left[cur] = *ord;
                *ord += 1;
                for &TreeEdge { to, .. } in tree.nodes[cur].neighbors() {
                    if Some(to) != par {
                        self.dfs(tree, to, Some(cur), d + 1, ord);
                    }
                }
                self.right[cur] = *ord;
            }

            pub fn children_query(&self, i: usize, d: usize) -> Option<(usize, usize)> {
                let d = d + self.depth[i];
                if self.bfs_ord.len() > d {
                    let l = lower_bound(&self.dfs_ord[d], &self.left[i]);
                    let r = lower_bound(&self.dfs_ord[d], &self.right[i]);
                    if l >= self.bfs_ord[d].len() {
                        return None;
                    }
                    if r <= 1 {
                        return None;
                    }
                    Some((self.bfs_ord[d][l], self.bfs_ord[d][r - 1] + 1))
                } else {
                    None
                }
            }

            pub fn me_query(&self, i: usize) -> (usize, usize) {
                (self.ord[i], self.ord[i] + 1)
            }

            pub fn ancestor(&self, i: usize, k: usize) -> Option<usize> {
                let mut p = i;
                for _ in 0..k {
                    match self.par[p] {
                        Some(x) => p = x,
                        _ => return None,
                    }
                }
                Some(p)
            }
        }
    }

    #[derive(Clone, Debug)]
    pub struct TreeEdge<T> {
        pub to: usize,
        pub weight: T,
    }

    #[derive(Clone, Debug)]
    pub struct TreeNode<T> {
        pub index: usize,
        pub parent: Option<TreeEdge<T>>,
        pub children: Vec<TreeEdge<T>>,
    }

    #[derive(Clone, Debug)]
    pub struct Tree<T> {
        pub nodes: Vec<TreeNode<T>>,
    }

    impl<T> TreeNode<T> {
        pub fn neighbors(&self) -> impl DoubleEndedIterator<Item = &TreeEdge<T>> {
            self.children.iter().chain(self.parent.iter())
        }

        pub fn neighbors_size(&self) -> usize {
            self.children.len() + self.parent.as_ref().map_or(0, |_| 1)
        }
    }

    impl<T: Copy> Tree<T> {
        pub fn new(size: usize) -> Self {
            Self {
                nodes: (0..size)
                    .map(|i| TreeNode {
                        index: i,
                        parent: None,
                        children: vec![],
                    })
                    .collect(),
            }
        }

        pub fn add_undirected(&mut self, edges: impl IntoIterator<Item = (usize, usize, T)>) {
            for (u, v, w) in edges {
                self.nodes[u].children.push(TreeEdge { to: v, weight: w });
                self.nodes[v].children.push(TreeEdge { to: u, weight: w });
            }
        }

        pub fn add_directed(&mut self, edges: impl IntoIterator<Item = (usize, usize, T)>) {
            for (p, c, w) in edges {
                assert!(self.nodes[c].parent.is_none());
                self.nodes[p].children.push(TreeEdge { to: c, weight: w });
                self.nodes[c].parent = Some(TreeEdge { to: p, weight: w });
            }
        }
    }

    impl<T> Tree<T> {
        pub fn len(&self) -> usize {
            self.nodes.len()
        }

        pub fn is_empty(&self) -> bool {
            self.nodes.is_empty()
        }
    }
}
0