Submission #55678131


Source Code Expand

use std::collections::VecDeque;

use itertools::Itertools;
use proconio::{input, marker::Usize1};

fn main() {
    input! { n: usize, m: u64 }

    let edge = {
        let mut edge = vec![Vec::new(); n];
        for _ in 1..n {
            input! { x: Usize1, y: Usize1 }
            edge[x].push(y);
            edge[y].push(x);
        }
        edge
    };

    // DFS starting at the node 0
    let mut dp = {
        let mut dp = vec![0; n];
        let mut stack = Vec::with_capacity(n);
        stack.push(0);
        let mut is_visited_once = vec![false; n];
        while let Some(&i) = stack.last() {
            if is_visited_once[i] {
                // postorder
                is_visited_once[i] = false;
                stack.pop();

                dp[i] = edge[i]
                    .iter()
                    .filter(|&&j| !is_visited_once[j])
                    .fold(1, |acc, &j| acc * (dp[j] + 1) % m);
            } else {
                // preorder
                is_visited_once[i] = true;
                for &j in edge[i].iter().filter(|&&j| !is_visited_once[j]) {
                    stack.push(j)
                }
            }
        }
        dp
    };
    // println!("DFS starting at 0: {:?}\n", dp);

    // Rerooting: BFS starting at the node 0
    let mut deque = VecDeque::with_capacity(n);
    deque.push_back((0, 1));
    let mut is_visited = vec![false; n];
    while let Some((i, left)) = deque.pop_front() {
        is_visited[i] = true;

        let children = Vec::from_iter(edge[i].iter().filter(|&&j| !is_visited[j]).copied());
        // println!("children: {:?}", children);

        let mut acc_l = vec![1; children.len()];
        for i in 1..children.len() {
            acc_l[i] = acc_l[i - 1] * (dp[children[i - 1]] + 1) % m
        }
        let mut acc_r = vec![1; children.len()];
        for i in (1..children.len()).rev() {
            acc_r[i - 1] = acc_r[i] * (dp[children[i]] + 1) % m
        }
        // println!("{:?}\n{:?}", acc_l, acc_r);

        for (i, c) in children.into_iter().enumerate() {
            let left = acc_l[i] * acc_r[i] % m * left % m + 1;
            dp[c] = (dp[c] * left) % m;
            deque.push_back((c, left))
        }
        // println!("{:?}\n", dp)
    }

    println!("{}", dp.into_iter().join("\n"))
}

Submission Info

Submission Time
Task V - Subtree
User nPk
Language Rust (rustc 1.70.0)
Score 100
Code Size 2388 Byte
Status AC
Exec Time 32 ms
Memory 15404 KiB

Judge Result

Set Name All
Score / Max Score 100 / 100
Status
AC × 36
Set Name Test Cases
All 0_00, 0_01, 0_02, 0_03, 1_00, 1_01, 1_02, 1_03, 1_04, 1_05, 1_06, 1_07, 1_08, 1_09, 1_10, 1_11, 1_12, 1_13, 1_14, 1_15, 1_16, 1_17, 1_18, 1_19, 1_20, 1_21, 1_22, 1_23, 1_24, 1_25, 1_26, 1_27, 1_28, 1_29, 1_30, 1_31
Case Name Status Exec Time Memory
0_00 AC 1 ms 1928 KiB
0_01 AC 0 ms 1988 KiB
0_02 AC 0 ms 1884 KiB
0_03 AC 0 ms 1812 KiB
1_00 AC 0 ms 1956 KiB
1_01 AC 0 ms 1896 KiB
1_02 AC 32 ms 12528 KiB
1_03 AC 32 ms 14152 KiB
1_04 AC 21 ms 15404 KiB
1_05 AC 22 ms 15304 KiB
1_06 AC 21 ms 14940 KiB
1_07 AC 23 ms 15396 KiB
1_08 AC 23 ms 13920 KiB
1_09 AC 25 ms 15000 KiB
1_10 AC 23 ms 13344 KiB
1_11 AC 27 ms 15100 KiB
1_12 AC 24 ms 13660 KiB
1_13 AC 25 ms 15100 KiB
1_14 AC 26 ms 13320 KiB
1_15 AC 29 ms 15012 KiB
1_16 AC 28 ms 12696 KiB
1_17 AC 30 ms 14424 KiB
1_18 AC 29 ms 12680 KiB
1_19 AC 31 ms 14312 KiB
1_20 AC 29 ms 12604 KiB
1_21 AC 31 ms 14164 KiB
1_22 AC 30 ms 12588 KiB
1_23 AC 32 ms 14012 KiB
1_24 AC 30 ms 12432 KiB
1_25 AC 32 ms 14204 KiB
1_26 AC 30 ms 12464 KiB
1_27 AC 32 ms 13992 KiB
1_28 AC 30 ms 12488 KiB
1_29 AC 32 ms 14132 KiB
1_30 AC 30 ms 12340 KiB
1_31 AC 32 ms 14064 KiB