|
| 1 | +fn getline() -> String { |
| 2 | + let mut ret = String::new(); |
| 3 | + std::io::stdin().read_line(&mut ret).unwrap(); |
| 4 | + ret |
| 5 | +} |
| 6 | + |
| 7 | +/// Verified by https://atcoder.jp/contests/abc198/submissions/21774342 |
| 8 | +mod mod_int { |
| 9 | + use std::ops::*; |
| 10 | + pub trait Mod: Copy { fn m() -> i64; } |
| 11 | + #[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] |
| 12 | + pub struct ModInt<M> { pub x: i64, phantom: ::std::marker::PhantomData<M> } |
| 13 | + impl<M: Mod> ModInt<M> { |
| 14 | + // x >= 0 |
| 15 | + pub fn new(x: i64) -> Self { ModInt::new_internal(x % M::m()) } |
| 16 | + fn new_internal(x: i64) -> Self { |
| 17 | + ModInt { x: x, phantom: ::std::marker::PhantomData } |
| 18 | + } |
| 19 | + pub fn pow(self, mut e: i64) -> Self { |
| 20 | + debug_assert!(e >= 0); |
| 21 | + let mut sum = ModInt::new_internal(1); |
| 22 | + let mut cur = self; |
| 23 | + while e > 0 { |
| 24 | + if e % 2 != 0 { sum *= cur; } |
| 25 | + cur *= cur; |
| 26 | + e /= 2; |
| 27 | + } |
| 28 | + sum |
| 29 | + } |
| 30 | + #[allow(dead_code)] |
| 31 | + pub fn inv(self) -> Self { self.pow(M::m() - 2) } |
| 32 | + } |
| 33 | + impl<M: Mod> Default for ModInt<M> { |
| 34 | + fn default() -> Self { Self::new_internal(0) } |
| 35 | + } |
| 36 | + impl<M: Mod, T: Into<ModInt<M>>> Add<T> for ModInt<M> { |
| 37 | + type Output = Self; |
| 38 | + fn add(self, other: T) -> Self { |
| 39 | + let other = other.into(); |
| 40 | + let mut sum = self.x + other.x; |
| 41 | + if sum >= M::m() { sum -= M::m(); } |
| 42 | + ModInt::new_internal(sum) |
| 43 | + } |
| 44 | + } |
| 45 | + impl<M: Mod, T: Into<ModInt<M>>> Sub<T> for ModInt<M> { |
| 46 | + type Output = Self; |
| 47 | + fn sub(self, other: T) -> Self { |
| 48 | + let other = other.into(); |
| 49 | + let mut sum = self.x - other.x; |
| 50 | + if sum < 0 { sum += M::m(); } |
| 51 | + ModInt::new_internal(sum) |
| 52 | + } |
| 53 | + } |
| 54 | + impl<M: Mod, T: Into<ModInt<M>>> Mul<T> for ModInt<M> { |
| 55 | + type Output = Self; |
| 56 | + fn mul(self, other: T) -> Self { ModInt::new(self.x * other.into().x % M::m()) } |
| 57 | + } |
| 58 | + impl<M: Mod, T: Into<ModInt<M>>> AddAssign<T> for ModInt<M> { |
| 59 | + fn add_assign(&mut self, other: T) { *self = *self + other; } |
| 60 | + } |
| 61 | + impl<M: Mod, T: Into<ModInt<M>>> SubAssign<T> for ModInt<M> { |
| 62 | + fn sub_assign(&mut self, other: T) { *self = *self - other; } |
| 63 | + } |
| 64 | + impl<M: Mod, T: Into<ModInt<M>>> MulAssign<T> for ModInt<M> { |
| 65 | + fn mul_assign(&mut self, other: T) { *self = *self * other; } |
| 66 | + } |
| 67 | + impl<M: Mod> Neg for ModInt<M> { |
| 68 | + type Output = Self; |
| 69 | + fn neg(self) -> Self { ModInt::new(0) - self } |
| 70 | + } |
| 71 | + impl<M> ::std::fmt::Display for ModInt<M> { |
| 72 | + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { |
| 73 | + self.x.fmt(f) |
| 74 | + } |
| 75 | + } |
| 76 | + impl<M: Mod> ::std::fmt::Debug for ModInt<M> { |
| 77 | + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { |
| 78 | + let (mut a, mut b, _) = red(self.x, M::m()); |
| 79 | + if b < 0 { |
| 80 | + a = -a; |
| 81 | + b = -b; |
| 82 | + } |
| 83 | + write!(f, "{}/{}", a, b) |
| 84 | + } |
| 85 | + } |
| 86 | + impl<M: Mod> From<i64> for ModInt<M> { |
| 87 | + fn from(x: i64) -> Self { Self::new(x) } |
| 88 | + } |
| 89 | + // Finds the simplest fraction x/y congruent to r mod p. |
| 90 | + // The return value (x, y, z) satisfies x = y * r + z * p. |
| 91 | + fn red(r: i64, p: i64) -> (i64, i64, i64) { |
| 92 | + if r.abs() <= 10000 { |
| 93 | + return (r, 1, 0); |
| 94 | + } |
| 95 | + let mut nxt_r = p % r; |
| 96 | + let mut q = p / r; |
| 97 | + if 2 * nxt_r >= r { |
| 98 | + nxt_r -= r; |
| 99 | + q += 1; |
| 100 | + } |
| 101 | + if 2 * nxt_r <= -r { |
| 102 | + nxt_r += r; |
| 103 | + q -= 1; |
| 104 | + } |
| 105 | + let (x, z, y) = red(nxt_r, r); |
| 106 | + (x, y - q * z, z) |
| 107 | + } |
| 108 | +} // mod mod_int |
| 109 | + |
| 110 | +macro_rules! define_mod { |
| 111 | + ($struct_name: ident, $modulo: expr) => { |
| 112 | + #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| 113 | + pub struct $struct_name {} |
| 114 | + impl mod_int::Mod for $struct_name { fn m() -> i64 { $modulo } } |
| 115 | + } |
| 116 | +} |
| 117 | +const MOD: i64 = 998_244_353; |
| 118 | +define_mod!(P, MOD); |
| 119 | +type MInt = mod_int::ModInt<P>; |
| 120 | + |
| 121 | +// Depends on MInt.rs |
| 122 | +fn fact_init(w: usize) -> (Vec<MInt>, Vec<MInt>) { |
| 123 | + let mut fac = vec![MInt::new(1); w]; |
| 124 | + let mut invfac = vec![0.into(); w]; |
| 125 | + for i in 1..w { |
| 126 | + fac[i] = fac[i - 1] * i as i64; |
| 127 | + } |
| 128 | + invfac[w - 1] = fac[w - 1].inv(); |
| 129 | + for i in (0..w - 1).rev() { |
| 130 | + invfac[i] = invfac[i + 1] * (i as i64 + 1); |
| 131 | + } |
| 132 | + (fac, invfac) |
| 133 | +} |
| 134 | + |
| 135 | +fn dfs(ch: &[Vec<usize>], c: &[i64], d: &[usize], invfac: &[MInt], v: usize) -> (MInt, i64) { |
| 136 | + let mut ans = MInt::new(1); |
| 137 | + let mut rest = c[v]; |
| 138 | + for &w in &ch[v] { |
| 139 | + let (subans, subrest) = dfs(ch, c, d, invfac, w); |
| 140 | + ans *= subans; |
| 141 | + rest += subrest; |
| 142 | + } |
| 143 | + if rest < d[v] as i64 { |
| 144 | + return (0.into(), 0); |
| 145 | + } |
| 146 | + for i in 0..d[v] { |
| 147 | + ans *= MInt::new(rest) - i as i64; |
| 148 | + } |
| 149 | + ans *= invfac[d[v]]; |
| 150 | + rest -= d[v] as i64; |
| 151 | + (ans, rest) |
| 152 | +} |
| 153 | + |
| 154 | +fn main() { |
| 155 | + let n = getline().trim().parse::<usize>().unwrap(); |
| 156 | + let p = getline().trim().split_whitespace() |
| 157 | + .map(|x| x.parse::<usize>().unwrap() - 1) |
| 158 | + .collect::<Vec<_>>(); |
| 159 | + let c = getline().trim().split_whitespace() |
| 160 | + .map(|x| x.parse::<i64>().unwrap()) |
| 161 | + .collect::<Vec<_>>(); |
| 162 | + let d = getline().trim().split_whitespace() |
| 163 | + .map(|x| x.parse::<usize>().unwrap()) |
| 164 | + .collect::<Vec<_>>(); |
| 165 | + let (_fac, invfac) = fact_init(1_000_001); |
| 166 | + let mut ch = vec![vec![]; n]; |
| 167 | + for i in 1..n { |
| 168 | + ch[p[i - 1]].push(i); |
| 169 | + } |
| 170 | + let ans = dfs(&ch, &c, &d, &invfac, 0); |
| 171 | + println!("{}", ans.0); |
| 172 | +} |
0 commit comments