use proconio::{input, marker::Usize1, fastout}; pub trait SegTreeMonoid{ type S: Clone; fn identity() -> Self::S; fn op(a: &Self::S, b: &Self::S) -> Self::S; } pub struct SegTree { n: usize, data: Vec, } impl SegTree { pub fn new(n: usize) -> Self { let n = n.next_power_of_two(); let data = vec![M::identity(); 2 * n]; SegTree{ n, data } } pub fn set(&mut self, i: usize, x: M::S) { let mut p = i + self.n; self.data[p] = x; while p > 1 { p /= 2; self.data[p] = M::op(&self.data[p << 1], &self.data[(p << 1) | 1]); } } pub fn from(a: Vec) -> Self{ let n = a.len().next_power_of_two(); let mut data = vec![M::identity(); 2*n]; for (i, v) in a.iter().enumerate(){ data[i+n] = v.clone(); } for i in (1..n).rev(){ data[i] = M::op(&data[2*i], &data[2*i+1]); } SegTree{ n, data, } } pub fn get(&self, p: usize)->M::S{ self.data[self.n+p].clone() } #[inline(always)] pub fn push(&mut self, i: usize, x: M::S) { let mut p = i + self.n; self.data[p] = M::op(&self.data[p], &x); while p > 1 { p /= 2; self.data[p] = M::op(&self.data[p << 1], &self.data[(p << 1) | 1]); } } pub fn prod(&self, l: usize, r: usize) -> M::S { let mut p_l = l + self.n; let mut p_r = r + self.n; let mut res_l = M::identity(); let mut res_r = M::identity(); while p_l < p_r { if p_l & 1 == 1 { res_l = M::op(&res_l, &self.data[p_l]); p_l += 1; } if p_r & 1 == 1 { p_r -= 1; res_r = M::op(&self.data[p_r], &res_r); } p_l >>= 1; p_r >>= 1; } M::op(&res_l, &res_r) } pub fn all_prod(&self)-> M::S { self.data[1].clone() } #[inline(always)] pub fn max_right(&self, mut l: usize, f: F) -> usize where F: Fn(&M::S)->bool { assert!(f(&M::identity())); // これはバグってくれないと多分デバックが悲惨 if l == self.n { return self.n } l += self.n; let mut ac = M::identity(); while { while l % 2 == 0 { l >>= 1; } if !f(&M::op(&ac, &self.data[l])) { while l < self.n { l <<= 1; let res = M::op(&ac, &self.data[l]); if f(&res) { ac = res; l += 1; } } return l - self.n; } ac = M::op(&ac, &self.data[l]); l += 1; let z = l as isize; (z & -z) != z } {} self.n } #[inline(always)] pub fn min_left(&self, mut r: usize, f: F) -> usize where F: Fn(&M::S) -> bool { assert!(f(&M::identity())); if r == 0 {return 0} r += self.n; let mut ac = M::identity(); while { r -= 1; while r > 1 && r % 2 == 1 { r >>= 1; } if !f(&M::op(&self.data[r], &ac)) { while r < self.n{ r = 2 * r + 1; let res = M::op(&self.data[r], &ac); if f(&res) { ac = res; r -= 1; } } return r + 1 - self.n; } ac = M::op(&self.data[r], &ac); let z = r as isize; z & -z != z } {} 0 } } struct M; impl SegTreeMonoid for M{ type S = i32; fn identity() -> Self::S { 0 } fn op(&a: &Self::S, &b: &Self::S) -> Self::S { a+b } } #[inline(always)] fn remove(x: i32, c: &mut SegTree, re: &mut SegTree){ let x = x as usize; c.push(x, -1); if c.get(x)==0{ let r = c.max_right(x, |&f| f==0); let mut l = c.min_left(x, |&f| f==0); if l==0{ if r < 1<<20{ re.push(x^r ,-1); } } else if r < 1<<20{ l -= 1; re.push(l^r, 1); re.push(l^x, -1); re.push(x^r,-1); } else { l -= 1; re.push(l^x, -1); } } else { re.push(0, -1); } } #[inline(always)] fn insert(x: i32, c: &mut SegTree, re: &mut SegTree){ let x = x as usize; if c.get(x)==0{ let r = c.max_right(x, |&f| f==0); let mut l = c.min_left(x, |&f| f==0); if l==0{ if r < 1<<20{ re.push(x^r ,1); } } else if r < 1<<20{ l -= 1; re.push(l^r, -1); re.push(l^x, 1); re.push(x^r,1); } else { l -= 1; re.push(l^x, 1); } } else { re.push(0, 1); } c.push(x, 1); } const MULTI: bool = false; #[fastout] fn solve(){ input!{ n: usize, q: usize, mut a: [i32; n], } let mut pre = a.clone(); let mut query = vec![(!0, -1, -1); q]; let mut qs = Vec::new(); for i in 0..q{ input!{ t: u8, } if t==1 { input!{ p: Usize1, x: i32, } query[i] = (p, pre[p], x); pre[p] = x; } else { input!{ r: usize, } qs.push((r, i)); } } let div = (n as f64*2.225/(q as f64).sqrt()).ceil() as usize; let mut ord = (0..qs.len()).collect::>(); ord.sort_unstable_by(|&u, &v| (qs[u].0/div).cmp(&(qs[v].0/div)).then(if qs[u].0/div%2==0{ qs[u].1.cmp(&qs[v].1) } else { qs[v].1.cmp(&qs[u].1) })); let mut ans = vec![0; qs.len()]; let mut cnt = SegTree::::new(1<<20); let mut res = SegTree::::new(1<<21); let (mut l, mut r) = (0, 0); for idx in ord{ let (left, right) = (qs[idx].0, qs[idx].1); while r < right{ if query[r].0!=!0{ let (p, u, v) = query[r]; a[p] = v; if p < l{ remove(u, &mut cnt, &mut res); insert(v, &mut cnt, &mut res); } } r += 1; } while l > left{ l -= 1; remove(a[l], &mut cnt, &mut res); } while r > right{ r -= 1; if query[r].0!=!0{ let (p, u, v) = query[r]; a[p] = u; if p < l{ remove(v, &mut cnt, &mut res); insert(u, &mut cnt, &mut res); } } } while l < left{ insert(a[l], &mut cnt, &mut res); l += 1; } ans[idx] = res.max_right(0, |&f| f==0); } for x in ans{ println!("{}", x); } } //#[fastout] fn main() { if MULTI{ input!{ t: usize, } for _ in 0..t{ solve(); } } else { solve(); } }