概要
要素の配列()に を満たすペアはいくつあるか.
連続区間なので, 累積和を用いて区間の和の余りを表せないか考える.
とすると, で表せる.
区間の場合には, となる.
ただ, 上式だと余りを求める際に両端が必要になるので, 2重ループになってしまい, まだ計算量を削る必要がある.
これは と変形できるので, を累積和として持てばで計算できる.
解答
fn main() {
let (n, m) = {
let i = read::<usize>();
(i[0], i[1])
};
let an = read::<usize>();
let mut rem = HashMap::new();
let mut cs = vec![0; n];
cs[0] = an[0] % m;
*rem.entry(cs[0]).or_insert(0) += 1;
for i in 1..n {
cs[i] = (cs[i - 1] + an[i]) % m;
*rem.entry(cs[i]).or_insert(0) += 1;
}
let ans = rem.iter()
.map(|(_, &num)| if num >= 2 { ncr(num, 2) } else { 0 })
.sum::<usize>();
println!("{}", ans + rem.get(&0).unwrap_or(&0));
}
Comments