結果

問題 No.900 aδδitivee
ユーザー niuezniuez
提出日時 2019-10-20 22:39:59
言語 Rust
(1.77.0 + proconio)
結果
AC  
実行時間 252 ms / 2,000 ms
コード長 10,115 bytes
コンパイル時間 14,921 ms
コンパイル使用メモリ 378,268 KB
実行使用メモリ 32,800 KB
最終ジャッジ日時 2024-07-02 17:34:03
合計ジャッジ時間 19,241 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 AC 1 ms
5,376 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 1 ms
5,376 KB
testcase_07 AC 239 ms
24,852 KB
testcase_08 AC 235 ms
24,576 KB
testcase_09 AC 232 ms
24,708 KB
testcase_10 AC 249 ms
24,728 KB
testcase_11 AC 236 ms
24,732 KB
testcase_12 AC 240 ms
24,576 KB
testcase_13 AC 238 ms
24,608 KB
testcase_14 AC 236 ms
24,720 KB
testcase_15 AC 232 ms
24,728 KB
testcase_16 AC 233 ms
24,612 KB
testcase_17 AC 252 ms
24,660 KB
testcase_18 AC 241 ms
24,448 KB
testcase_19 AC 241 ms
24,720 KB
testcase_20 AC 235 ms
24,732 KB
testcase_21 AC 234 ms
24,600 KB
testcase_22 AC 180 ms
32,768 KB
testcase_23 AC 175 ms
32,640 KB
testcase_24 AC 188 ms
32,768 KB
testcase_25 AC 180 ms
32,768 KB
testcase_26 AC 184 ms
32,768 KB
testcase_27 AC 177 ms
32,800 KB
testcase_28 AC 179 ms
32,600 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

pub struct DirectedTree {
    n: usize,
    r: usize,
    g: Vec<Vec<usize>>,
    p: Vec<Option<(usize, usize)>>,
}

impl DirectedTree {
    pub fn new<I: IntoIterator<Item=(usize, usize)>>(n: usize, es: I) -> Self {
        let mut g: Vec<_> = (0..n).map(|_| Vec::new()).collect();
        let mut p = vec![None; n];
        for (u, v) in es {
            p[v] = Some((u, g[u].len()));
            g[u].push(v);
        }
        DirectedTree {
            n: n,
            r: (0..n).find(|&x| p[x].is_none()).unwrap(),
            g: g,
            p: p,
        }
    }

    pub fn next(&self, v: usize) -> std::slice::Iter<usize> { self.g[v].iter() }
    pub fn parent(&self, v: usize) -> Option<usize> { self.p[v].map(|(u, i)| self.g[u][i]) }
    pub fn root(&self) -> usize { self.r }
    pub fn len(&self) -> usize { self.n }
}

pub struct HeavyLightDecomposition {
    din: Vec<usize>,
    dout: Vec<usize>,
    sz: Vec<usize>,
    seq: Vec<usize>,
    heavy: Vec<Option<usize>>,
    next: Vec<Option<usize>>,
    par: Vec<Option<usize>>,
}

impl HeavyLightDecomposition {
    fn dfs_sz(&mut self, tree: &DirectedTree, v: usize) {
        self.sz[v] = 1;
        for &u in tree.next(v) {
            self.dfs_sz(tree, u);
            self.par[u] = Some(v);
            self.sz[v] += self.sz[u];
        }
        self.heavy[v] = tree.next(v).max_by_key(|&&i| self.sz[i]).map(|&x| x);
    }
    fn dfs_hld(&mut self, tree: &DirectedTree, v: usize, mut t: usize) -> usize {
        self.din[v] = t;
        self.seq.push(v);
        t = t + 1;
        if let Some(h) = self.heavy[v] {
            self.next[h] = self.next[v];
            t = self.dfs_hld(tree, h, t);
            for &u in tree.next(v).filter(|&&u| u != h) {
                self.next[u] = Some(u);
                t = self.dfs_hld(tree, u, t);
            }
        }
        self.dout[v] = t;
        t
    }
    pub fn build(tree: &DirectedTree) -> Self {
        let n = tree.len();
        let mut hld = HeavyLightDecomposition {
            din: vec![0; n],
            dout: vec![0; n],
            seq: Vec::new(),
            sz: vec![0; n],
            heavy: vec![None; n],
            next: vec![None; n],
            par: vec![None; n],
        };
        hld.dfs_sz(tree, tree.root());
        hld.dfs_hld(tree, tree.root(), 0);
        hld
    }
    pub fn sequence(&self) -> std::slice::Iter<usize> { self.seq.iter() }
    pub fn lca(&self, mut v: usize, mut u: usize) -> usize {
        loop {
            if self.din[u] > self.din[v] { std::mem::swap(&mut v, &mut u); }
            if self.next[u] == self.next[v] { break }
            v = self.par[self.next[v].unwrap()].unwrap();
        }
        u
    }
    pub fn path(&self, mut v: usize, mut u: usize, edge: bool) -> (Vec<std::ops::Range<usize>>, Vec<std::ops::Range<usize>>) {
        let mut l = Vec::new();
        let mut r = Vec::new();
        loop {
            if self.din[u] > self.din[v] {
                std::mem::swap(&mut v, &mut u);
                std::mem::swap(&mut l, &mut r);
            }
            if self.next[u] == self.next[v] {
                let e = if edge { 1 } else { 0 };
                l.push(self.din[u] + e..self.din[v] + 1);
                break
            }
            else {
                let ne = self.next[v].unwrap();
                l.push(self.din[ne]..self.din[v] + 1);
                v = self.par[ne].unwrap();
            }
        }
        (l, r)
    }
    pub fn subtree(&self, v: usize, edge: bool) -> std::ops::Range<usize> { self.din[v] + if edge { 1 } else { 0 }..self.dout[v] }
}


pub trait Magma: Sized + Clone {
  fn op(&self, rhs: &Self) -> Self;
}

pub trait Associative: Magma {}

pub trait Unital: Magma {
  fn identity() -> Self;
}

pub trait Monoid: Magma + Associative + Unital {}

pub trait Pow: Magma {
    fn pow(&self, p: usize) -> Self;
}

pub trait Reverse: Magma {
    fn reverse(&self) -> Self;
}

pub trait Inv: Magma {
    fn inv(&self) -> Self;
}

pub trait Effect<E: Monoid> {
    fn effect(&self, e: &E) -> Self;
}

impl<T: Magma + Associative + Unital> Monoid for T {}

use std::ops::Range;

pub struct LazySegmentTree<T: Monoid + Effect<E>, E: Monoid + Pow> {
    node: Vec<T>,
    lazy: Vec<E>,
    sz: usize,
}

impl<T: Monoid + Effect<E>, E: Monoid + Pow> LazySegmentTree<T, E> {
    pub fn init(arr: &[T]) -> Self {
        let mut sz = 1;
        while sz < arr.len() { sz *= 2 }
        let mut node = vec![T::identity(); sz << 1];
        let lazy = vec![E::identity(); sz << 1];
        for i in 0..arr.len() { node[i + sz] = arr[i].clone(); }
        for i in (1..sz).rev() { node[i] = node[i << 1].op(&node[(i << 1) + 1]); }
        Self { node: node, lazy: lazy, sz: sz }
    }

    fn push(&mut self, i: usize, sz: usize) {
        self.node[i] = self.node[i].effect(&self.lazy[i].pow(sz));
        if (i << 1) < self.node.len() {
            self.lazy[i << 1] = self.lazy[i << 1].op(&self.lazy[i]);
            self.lazy[(i << 1) + 1] = self.lazy[(i << 1) + 1].op(&self.lazy[i]);
        }
        self.lazy[i] = E::identity();
    }

    fn update_raw(&mut self, i: usize, a: usize, b: usize, l: usize, r: usize, e: &E) {
        self.push(i, r - l);
        if b <= l || r <= a { return; }
        else if a <= l && r <= b {
            self.lazy[i] = self.lazy[i].op(e);
            self.push(i, r - l);
        }
        else {
            self.update_raw(i << 1, a, b, l, (l + r) >> 1, e);
            self.update_raw((i << 1) + 1, a, b, (l + r) >> 1, r, e);
            self.node[i] = self.node[i << 1].op(&self.node[(i << 1) + 1]);
        }
    }

    pub fn effect(&mut self, ran: Range<usize>, e: E) {
        let sz = self.sz;
        self.update_raw(1, ran.start, ran.end, 0, sz, &e);
    }

    fn fold_raw(&mut self, i: usize, a: usize, b: usize, l: usize, r: usize) -> T {
        self.push(i, r - l);
        if b <= l || r <= a { T::identity() }
        else if a <= l && r <= b { self.node[i].clone() }
        else {
            self.fold_raw(i << 1, a, b, l, (l + r) >> 1)
                .op(&self.fold_raw((i << 1) + 1, a, b, (l + r) >> 1, r))
        }
    }

    pub fn fold(&mut self, ran: Range<usize>) -> T {
        let sz = self.sz;
        self.fold_raw(1, ran.start, ran.end, 0, sz)
    }
}

/// Reading from standard input
///
/// `input!` is useful for competition programming.
/// There are some forms.
///
/// - Tuple
///
/// ```
/// use cp_rust_library::*;
/// input! { source = "2 3", ab: (usize, usize), }
/// assert_eq!(ab.0, 2);
/// assert_eq!(ab.1, 3);
/// ```
///
/// - Array
/// ```
/// use cp_rust_library::*;
/// input! { source = "1 2 3 4", a: [usize; 4], }
/// assert_eq!(a, vec![1, 2, 3, 4]);
/// ```
///
/// - String -> Vec<char>
/// ```
/// use cp_rust_library::*;
/// input! { source = "qwerty", s: chars, }
/// assert_eq!('q', s[0]);
/// ```
///
/// - Other
/// ```
/// use cp_rust_library::*;
/// input! { source = "123", a: usize, }
/// assert_eq!(123, a);
/// ```
/// 
/// This macro will use parse::<$type>() to parse string.

#[macro_export]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_rec!{ iter, $($r)* }
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_rec!{ iter, $($r)* }
    };
}

#[macro_export]
macro_rules! input_rec {
    ($iter:expr) => {};
    ($iter:expr, ) => {};
    ($iter:expr, $var:ident : $t:tt, $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_rec! { $iter, $($r)* }
    };
}

#[macro_export]
macro_rules! read_value {

    // tuple
    ($iter:expr, ( $($t:tt), * )) => {
        ( $(read_value!($iter, $t)), * )
    };
    
    // array
    ($iter:expr, [ $t:tt; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, query) => {{
        let t = $iter.next().unwrap().parse::<usize>().expect("error");
        if t == 1 {
            (t, read_value!($iter, usize), read_value!($iter, usize))
        }
        else {
            (t, read_value!($iter, usize), 0)
        }
    }};
    
    // string
    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };
    
    // any other
    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };

}


#[derive(Clone)]
struct Am(i64);

impl Magma for Am {
    fn op(&self, right: &Self) -> Self { Am(self.0 + right.0) }
}
impl Associative for Am {}

impl Unital for Am {
    fn identity() -> Self { Am(0) }
}

#[derive(Clone)]
struct Uq(i64);

impl Magma for Uq {
    fn op(&self, right: &Self) -> Self {
        Uq(self.0 + right.0)
    }
}
impl Associative for Uq {}
impl Unital for Uq {
    fn identity() -> Self { Uq(0) }
}
impl Pow for Uq {
    fn pow(&self, len: usize) -> Self { Uq(self.0 * len as i64) }
}
impl Effect<Uq> for Am {
    fn effect(&self, u: &Uq) -> Am {
        Am(self.0 + u.0)
    }
}


fn main() {
    input! {
        n: usize,
        edges: [(usize, usize, usize); n - 1],
        q: usize,
        qs: [query; q],
    }
    let mut w = vec![0; n + 1];
    for &(_, v, a) in edges.iter() {
        w[v] = a as i64;
    }

    let hld = HeavyLightDecomposition::build(
        &DirectedTree::new(n, edges.iter().map(|x| (x.0, x.1)))
        );
    let seq = hld.sequence().map(|&v| w[v]).collect::<Vec<_>>();
    let mut seg = LazySegmentTree::init(
        &seq.into_iter().map(|x| Am(x)).collect::<Vec<_>>()
        );
    for (t, a, b) in qs {
        if t == 1 {
            seg.effect(hld.subtree(a, true), Uq(b as i64));
        }
        else {
            let (l, r) = hld.path(0, a, true);
            println!("{}", 
                    l.iter().fold(Am::identity(), |lm, ran| lm.op(&seg.fold(ran.clone()))).op(
                    &r.iter().fold(Am::identity(), |lm, ran| lm.op(&seg.fold(ran.clone())))).0
                     );
        }
    }
}
0