結果

問題 No.899 γatheree
ユーザー ngtkanangtkana
提出日時 2024-05-07 19:49:08
言語 Rust
(1.77.0 + proconio)
結果
AC  
実行時間 533 ms / 2,000 ms
コード長 9,771 bytes
コンパイル時間 18,885 ms
コンパイル使用メモリ 377,116 KB
実行使用メモリ 24,740 KB
最終ジャッジ日時 2024-05-07 19:49:40
合計ジャッジ時間 26,688 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 0 ms
5,248 KB
testcase_01 AC 1 ms
5,248 KB
testcase_02 AC 1 ms
5,248 KB
testcase_03 AC 1 ms
5,376 KB
testcase_04 AC 1 ms
5,376 KB
testcase_05 AC 1 ms
5,376 KB
testcase_06 AC 529 ms
24,304 KB
testcase_07 AC 497 ms
24,432 KB
testcase_08 AC 525 ms
24,560 KB
testcase_09 AC 501 ms
24,308 KB
testcase_10 AC 505 ms
24,432 KB
testcase_11 AC 523 ms
24,560 KB
testcase_12 AC 499 ms
24,308 KB
testcase_13 AC 521 ms
24,304 KB
testcase_14 AC 493 ms
24,048 KB
testcase_15 AC 533 ms
24,304 KB
testcase_16 AC 499 ms
24,184 KB
testcase_17 AC 519 ms
24,556 KB
testcase_18 AC 497 ms
24,180 KB
testcase_19 AC 507 ms
24,304 KB
testcase_20 AC 532 ms
24,176 KB
testcase_21 AC 488 ms
24,740 KB
testcase_22 AC 521 ms
24,736 KB
testcase_23 AC 494 ms
24,620 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

use crate::cmpmore::CmpMore;
use crate::lazy_segtree::LazySegtree;
use proconio::input;
use std::collections::VecDeque;

fn main() {
    input! {
        n: usize,
        edges: [(usize, usize); n - 1],
        a: [u64; n],
        q: usize,
        queries: [usize; q],
    }
    let mut g = vec![vec![]; n];
    for (i, j) in edges {
        g[i].push(j);
        g[j].push(i);
    }
    let mut queue = VecDeque::from(vec![0]);
    let mut position = vec![usize::MAX; n];
    let mut sorted = Vec::new();
    let mut parent = vec![usize::MAX; n];
    while let Some(i) = queue.pop_front() {
        position[i] = sorted.len();
        sorted.push(i);
        for &j in &g[i] {
            if position[j] == usize::MAX {
                queue.push_back(j);
                parent[j] = i;
            }
        }
    }
    let mut seg = sorted.iter().map(|&i| a[i]).collect::<LazySegtree<O>>();
    let mut children = vec![(usize::MAX, usize::MIN); n];
    let mut grandchildren = vec![(usize::MAX, usize::MIN); n];
    for &i in sorted.iter().rev() {
        for &j in &g[i] {
            if parent[i] == j {
                continue;
            }
            children[i].0.change_min(position[j]);
            children[i].1.change_max(position[j]);
            grandchildren[i].0.change_min(children[j].0);
            grandchildren[i].1.change_max(children[j].1);
        }
    }
    for &i in &queries {
        let mut ans = 0;
        ans += seg.get(position[i]);
        if children[i].0 != usize::MAX {
            ans += seg.fold(children[i].0..=children[i].1);
            seg.range_apply(children[i].0..=children[i].1, &Some(0));
        }
        if grandchildren[i].0 != usize::MAX {
            ans += seg.fold(grandchildren[i].0..=grandchildren[i].1);
            seg.range_apply(grandchildren[i].0..=grandchildren[i].1, &Some(0));
        }
        let j = parent[i];
        if j != usize::MAX {
            ans += seg.get(position[j]);
            ans -= seg.get(position[i]);
            seg.range_apply(position[j]..=position[j], &Some(0));
            if children[j].0 != usize::MAX {
                ans += seg.fold(children[j].0..=children[j].1);
                seg.range_apply(children[j].0..=children[j].1, &Some(0));
            }
            let k = parent[j];
            if k != usize::MAX {
                ans += seg.get(position[k]);
                seg.range_apply(position[k]..=position[k], &Some(0));
            }
        }
        seg.range_apply(position[i]..=position[i], &Some(ans));
        println!("{}", ans);
    }
}

enum O {}
impl lazy_segtree::Op for O {
    type Operator = Option<u64>;
    type Value = u64;

    fn identity() -> Self::Value {
        0
    }

    fn op(lhs: &Self::Value, rhs: &Self::Value) -> Self::Value {
        lhs + rhs
    }

    fn apply(op: &Self::Operator, value: &Self::Value) -> Self::Value {
        op.unwrap_or(*value)
    }

    fn identity_op() -> Self::Operator {
        None
    }

    fn compose(op: &Self::Operator, other: &Self::Operator) -> Self::Operator {
        op.or(*other)
    }
}

// cmpmore {{{
// https://ngtkana.github.io/ac-adapter-rs/cmpmore/index.html

#[allow(dead_code)]
mod cmpmore {
    pub fn change_min<T: PartialOrd>(lhs: &mut T, rhs: T) {
        if *lhs > rhs {
            *lhs = rhs;
        }
    }
    pub fn change_max<T: PartialOrd>(lhs: &mut T, rhs: T) {
        if *lhs < rhs {
            *lhs = rhs;
        }
    }
    #[macro_export]
    macro_rules! change_min {
        ($lhs:expr, $rhs:expr) => {
            let rhs = $rhs;
            let lhs = $lhs;
            $crate::cmpmore::change_min(lhs, rhs);
        };
    }
    #[macro_export]
    macro_rules! change_max {
        ($lhs:expr, $rhs:expr) => {
            let rhs = $rhs;
            let lhs = $lhs;
            $crate::cmpmore::change_max(lhs, rhs);
        };
    }
    pub trait CmpMore: PartialOrd + Sized {
        fn change_min(&mut self, rhs: Self) {
            change_min(self, rhs)
        }
        fn change_max(&mut self, rhs: Self) {
            change_max(self, rhs)
        }
    }
    impl<T: PartialOrd + Sized> CmpMore for T {}
}
// }}}
// lazy_segtree {{{
// https://ngtkana.github.io/ac-adapter-rs/lazy_segtree/index.html

#[allow(dead_code)]
mod lazy_segtree {
    use std::iter::FromIterator;
    use std::mem::replace;
    use std::ops::RangeBounds;
    pub trait Op {
        type Value;
        type Operator: PartialEq;
        fn identity() -> Self::Value;
        fn op(lhs: &Self::Value, rhs: &Self::Value) -> Self::Value;
        fn apply(op: &Self::Operator, value: &Self::Value) -> Self::Value;
        fn identity_op() -> Self::Operator;
        fn compose(op: &Self::Operator, other: &Self::Operator) -> Self::Operator;
    }
    #[derive(Debug, Clone)]
    pub struct LazySegtree<O: Op> {
        values: Vec<O::Value>,
        operators: Vec<O::Operator>,
    }
    impl<O: Op> LazySegtree<O> {
        pub fn new(values: &[O::Value]) -> Self
        where
            O::Value: Clone,
            O::Operator: Clone,
        {
            let values_ = values;
            let n = values_.len();
            let mut values = vec![O::identity(); 2 * n];
            values[n..].clone_from_slice(values_);
            for i in (1..n).rev() {
                values[i] = O::op(&values[i * 2], &values[i * 2 + 1]);
            }
            Self {
                values,
                operators: vec![O::identity_op(); 2 * n],
            }
        }

        pub fn range_apply<R: RangeBounds<usize>>(&mut self, range: R, f: &O::Operator) {
            let n = self.operators.len() / 2;
            let (l, r) = open(range, n);
            if l == r {
                return;
            }
            let l = n + l;
            let r = n + r;
            for p in (0..usize::BITS - r.leading_zeros()).rev() {
                self.push(l >> p);
                self.push((r - 1) >> p);
            }
            {
                let mut l = l;
                let mut r = r;
                while l < r {
                    if l & 1 != 0 {
                        self.operators[l] = O::compose(f, &self.operators[l]);
                        l += 1;
                    }
                    if r & 1 != 0 {
                        r -= 1;
                        self.operators[r] = O::compose(f, &self.operators[r]);
                    }
                    l >>= 1;
                    r >>= 1;
                }
            }
            for p in 1..usize::BITS - r.leading_zeros() {
                self.update(l >> p);
                self.update((r - 1) >> p);
            }
        }

        pub fn fold<R: RangeBounds<usize>>(&mut self, range: R) -> O::Value {
            let n = self.operators.len() / 2;
            let (mut l, mut r) = open(range, n);
            if l == r {
                return O::identity();
            }
            l += n;
            r += n;
            for p in (0..usize::BITS - r.leading_zeros()).rev() {
                self.push(l >> p);
                self.push((r - 1) >> p);
            }
            for p in 1..usize::BITS - r.leading_zeros() {
                self.update(l >> p);
                self.update((r - 1) >> p);
            }
            let mut left = O::identity();
            let mut right = O::identity();
            while l < r {
                if l & 1 != 0 {
                    left = O::op(&left, &O::apply(&self.operators[l], &self.values[l]));
                    l += 1;
                }
                if r & 1 != 0 {
                    r -= 1;
                    right = O::op(&O::apply(&self.operators[r], &self.values[r]), &right);
                }
                l >>= 1;
                r >>= 1;
            }
            O::op(&left, &right)
        }

        pub fn get(&self, i: usize) -> O::Value
        where
            O::Value: Clone,
        {
            let mut i = self.operators.len() / 2 + i;
            let mut value = self.values[i].clone();
            while i > 0 {
                value = O::apply(&self.operators[i], &value);
                i >>= 1;
            }
            value
        }

        pub fn collect(&self) -> Vec<O::Value>
        where
            O::Value: Clone,
        {
            (0..self.operators.len() / 2).map(|i| self.get(i)).collect()
        }

        fn push(&mut self, i: usize) {
            let a = replace(&mut self.operators[i], O::identity_op());
            self.values[i] = O::apply(&a, &self.values[i]);
            if i < self.operators.len() / 2 {
                self.operators[i << 1] = O::compose(&a, &self.operators[i << 1]);
                self.operators[i << 1 | 1] = O::compose(&a, &self.operators[i << 1 | 1]);
            }
        }

        fn update(&mut self, i: usize) {
            self.values[i] = O::op(
                &O::apply(&self.operators[i << 1], &self.values[i << 1]),
                &O::apply(&self.operators[i << 1 | 1], &self.values[i << 1 | 1]),
            )
        }
    }
    impl<O: Op> FromIterator<O::Value> for LazySegtree<O>
    where
        O::Value: Clone,
        O::Operator: Clone,
    {
        fn from_iter<T: IntoIterator<Item = O::Value>>(iter: T) -> Self {
            Self::new(&iter.into_iter().collect::<Vec<_>>())
        }
    }
    fn open<B: RangeBounds<usize>>(bounds: B, n: usize) -> (usize, usize) {
        use std::ops::Bound;
        let start = match bounds.start_bound() {
            Bound::Unbounded => 0,
            Bound::Included(&x) => x,
            Bound::Excluded(&x) => x + 1,
        };
        let end = match bounds.end_bound() {
            Bound::Unbounded => n,
            Bound::Included(&x) => x + 1,
            Bound::Excluded(&x) => x,
        };
        (start, end)
    }
}
// }}}
0