https://atcoder.jp/contests/abc384/tasks/abc384_d
繰り返し部分を除いて、数列Aの中か両端で和がSになる範囲を探せばいいですが、尺取り法でO(N)でできます。
// Repeated Sequence #![allow(non_snake_case)] //////////////////// library //////////////////// fn read<T: std::str::FromStr>() -> T { let mut line = String::new(); std::io::stdin().read_line(&mut line).ok(); line.trim().parse().ok().unwrap() } fn read_vec<T: std::str::FromStr>() -> Vec<T> { read::<String>().split_whitespace() .map(|e| e.parse().ok().unwrap()).collect() } fn YesNo(b: bool) -> String { return if b { "Yes" } else { "No" }.to_string() } //////////////////// process //////////////////// fn read_input() -> (i64, Vec<i64>) { let v: Vec<i64> = read_vec(); let S = v[1]; let A: Vec<i64> = read_vec(); (S, A) } fn accumulate(A: &Vec<i64>) -> Vec<i64> { let mut acc: Vec<i64> = vec![0]; for &a in A.iter() { acc.push(acc[acc.len()-1] + a) } acc } fn is_equal_mid(S: i64, acc: &Vec<i64>) -> bool { let mut k = 0; let mut l = 0; while l < acc.len() { if acc[l] - acc[k] == S { return true } else if acc[l] - acc[k] < S { l += 1 } else { k += 1 } } false } fn is_equal_edge(S: i64, acc: &Vec<i64>) -> bool { is_equal_mid(*acc.iter().last().unwrap() - S, acc) } fn F(S: i64, A: Vec<i64>) -> bool { let acc = accumulate(&A); let sum = *acc.iter().last().unwrap(); let r = S % sum; is_equal_mid(r, &acc) || is_equal_edge(r, &acc) } fn main() { let (S, A) = read_input(); println!("{}", YesNo(F(S, A))) }