use proconio::input; use std::collections::BTreeSet; // Thanks: // https://namakeru-engineer.com/intervalset/ pub struct IntervalSet where T: Ord + Copy + Default + std::ops::Sub + std::ops::Add, { set: BTreeSet<(T, T)>, sum: T, } impl IntervalSet where T: Ord + Copy + Default + std::ops::Sub + std::ops::Add, { pub fn new() -> Self { Self { set: BTreeSet::new(), sum: T::default(), } } // x を含む区間 [l, r) を返す // 存在しない場合は None を返す pub fn get(&self, x: T) -> Option<(T, T)> { if let Some(&(l, r)) = self.set.range(..(x, x)).next_back() { if l <= x && x < r { return Some((l, r)); } } if let Some(&(l, r)) = self.set.range((x, x)..).next() { if l <= x && x < r { return Some((l, r)); } } None } // x より左にある区間 [l, r) を返す // 存在しない場合は None を返す pub fn get_left(&self, x: T) -> Option<(T, T)> { for &(l, r) in self.set.range(..(x, x)).rev() { if r <= x { return Some((l, r)); } } None } // x より右にある区間 [l, r) を返す // 存在しない場合は None を返す pub fn get_right(&self, x: T) -> Option<(T, T)> { for &(l, r) in self.set.range((x, x)..) { if x < l { return Some((l, r)); } } None } // 追加されている区間を返す pub fn get_all(&self) -> Vec<(T, T)> { self.set.iter().map(|&(l, r)| (l, r)).collect() } // 追加されている区間の合計を返す pub fn sum(&self) -> T { self.sum } // 区間の個数を返す pub fn len(&self) -> usize { self.set.len() } // [l, r) が追加されている場合は true を返す // そうでない場合は false を返す pub fn is_covered(&self, l: T, r: T) -> bool { assert!(l <= r); if l == r { return true; } if let Some((_a, b)) = self.get(l) { if r <= b { return true; } } false } // mex を返す pub fn mex(&self, x: T) -> T { if let Some((_a, b)) = self.get(x) { return b; } x } // 区間 [l, r) を追加する pub fn insert(&mut self, l: T, r: T) { assert!(l <= r); if l == r { return; } let mut l = l; let mut r = r; if let Some((a, b)) = self.get_left(l) { if b == l { self.set.remove(&(a, b)); self.sum = self.sum - (b - a); l = a; } } if let Some((a, b)) = self.get(l) { self.set.remove(&(a, b)); self.sum = self.sum - (b - a); l = a; r = r.max(b); } while let Some((a, b)) = self.get_right(l) { if a <= r { self.set.remove(&(a, b)); self.sum = self.sum - (b - a); r = r.max(b); } else { break; } } self.set.insert((l, r)); self.sum = self.sum + (r - l); } // 区間 [l, r) を削除する pub fn remove(&mut self, l: T, r: T) { assert!(l <= r); if l == r { return; } if let Some((a, b)) = self.get(l) { self.set.remove(&(a, b)); self.sum = self.sum - (b - a); if a < l { self.set.insert((a, l)); self.sum = self.sum + (l - a); } if r < b { self.set.insert((r, b)); self.sum = self.sum + (b - r); } } while let Some((a, b)) = self.get_right(l) { if r <= a { break; } self.set.remove(&(a, b)); self.sum = self.sum - (b - a); if r < b { self.set.insert((r, b)); self.sum = self.sum + (b - r); } } } // 空にする pub fn clear(&mut self) { self.set.clear(); self.sum = T::default(); } } fn main() { input! { n: usize, hs: [usize; n], } let mut it = IntervalSet::new(); for (i, h) in hs.into_iter().enumerate() { if i % 2 == 0 { it.insert(0, h) } else { it.remove(0, h) } println!("{}", it.sum()); } }