// 尺取りしろという話だがどういうことか use std::io::Write; use std::collections::*; type Map = BTreeMap; type Set = BTreeSet; type Deque = VecDeque; fn main() { input! { n: usize, k: i64, m: i64, b: [i64; n], c: [i64; n], } let mut deq = Deque::<(i64, i64)>::new(); let mut cnt = 0; let mut sum = 0; let mut ans = 0; for (mut c, b) in b.into_iter().zip(c) { while deq.len() > 0 && cnt - deq[0].0 + c >= k { let (p, q) = deq[0]; // 0 <= i < q, sum + (b - p)i = 0 (mod M) let (x, y, g) = ext_gcd(m, b - p); if sum % g == 0 { let i = ((-sum / g) * y).rem_euclid(m / g); if i < q { ans += (q - i - 1) / (m / g) + 1; } } deq.pop_front(); cnt -= q; sum = (sum + m - p * q % m) % m; } if cnt + c > k && deq.len() > 0 { let need = cnt + c - k; let (p, q) = deq[0]; assert!(need < q); deq[0].1 -= need; let q = need; // 0 <= i < q, sum + (b - p)i = 0 (mod M) let (x, y, g) = ext_gcd(m, b - p); if sum % g == 0 { let i = ((-sum / g) * y).rem_euclid(m / g); if i < q { ans += (q - i - 1) / (m / g) + 1; } } cnt -= q; sum = (sum + m - p * q % m) % m; } if c > k { if k * b % m == 0 { ans += c - k; } c = k; } deq.push_back((b, c)); cnt += b; sum = (sum + b * c) % m; } if sum % m == 0 { ans += 1; } println!("{}", ans); } // ---------- begin input macro ---------- // reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 #[macro_export] macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); input_inner!{iter, $($r)*} }; ($($r:tt)*) => { let s = { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); s }; let mut iter = s.split_whitespace(); input_inner!{iter, $($r)*} }; } #[macro_export] macro_rules! input_inner { ($iter:expr) => {}; ($iter:expr, ) => {}; ($iter:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($iter, $t); input_inner!{$iter $($r)*} }; } #[macro_export] macro_rules! read_value { ($iter:expr, ( $($t:tt),* )) => { ( $(read_value!($iter, $t)),* ) }; ($iter:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($iter, $t)).collect::>() }; ($iter:expr, chars) => { read_value!($iter, String).chars().collect::>() }; ($iter:expr, bytes) => { read_value!($iter, String).bytes().collect::>() }; ($iter:expr, usize1) => { read_value!($iter, usize) - 1 }; ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().expect("Parse error") }; } // ---------- end input macro ---------- // return (a, b, g) // ax + by = gcd(x, y) // gcd(x, y) = 0 の時は(0, 0) が返る pub fn ext_gcd(x: i64, y: i64) -> (i64, i64, i64) { if y == 0 { return (x.signum(), 0, x.abs()); } let q = x.div_euclid(y); let r = x.rem_euclid(y); let p = ext_gcd(y, r); (p.1, p.0 - q * p.1, p.2) }