fn main() { input!{ n: usize, _f: usize, a: [u64; n], b: [u64; n], c: [u64; n], } let mut cur_dp = vec![0u128; n+1]; cur_dp[0] = 1; // mask値を事前計算(下位桁、上位桁) let mask1 = (1 << 64)-1; let mask2 = !0; // i人 for i in 0..n { let mut next_dp = vec![0u128; n+1]; // 状態j for j in 0..=i { // 1つ目の手 let next1 = cur_dp[j] << a[i]; next_dp[j] |= next1 & mask1; next_dp[j+1] |= (next1 & mask2) >> 64; // 2つ目の手 let next2 = cur_dp[j] << b[i]; next_dp[j] |= next2 & mask1; next_dp[j+1] |= (next2 & mask2) >> 64; // 3つ目の手 let next3 = cur_dp[j] << c[i]; next_dp[j] |= next3 & mask1; next_dp[j+1] |= (next3 & mask2) >> 64; } let mut ret = 0; for j in 0..=i { ret += next_dp[j].count_ones(); } println!("{}", ret); swap(&mut cur_dp, &mut next_dp); } } // const MOD17: usize = 1000000007; // const MOD93: usize = 998244353; // const INF: usize = 1 << 60; // let dx = vec![!0, 0, 1, 0]; // 上左下右 // let dy = vec![0, !0, 0, 1]; // 上左下右 // let d = vec!{(!0, 0), (0, !0), (1, 0), (0, 1)}; // 上左下右 #[allow(unused)] use proconio::{input, marker::Chars, marker::Usize1}; #[allow(unused)] use std::{ mem::swap, cmp::min, cmp::max, cmp::Reverse, collections::HashSet, collections::BTreeSet, collections::HashMap, collections::BTreeMap, collections::BinaryHeap, collections::VecDeque, iter::FromIterator, }; // 配列のスペース区切り出力 #[allow(unused)] fn vec_print<T: std::fmt::Display>(vec: &Vec<T>) { let sz = vec.len(); for i in 0..sz-1 { print!("{} ", vec[i]); } println!("{}", vec[sz-1]); }