use std::collections::*; use std::io::Write; type Map = BTreeMap; type Set = BTreeSet; type Deque = VecDeque; fn run() { input! { n: usize, m: usize, a: [u32; n], l: [usize; m], r: [usize; m], x: [usize; m], L: [usize; m], R: [usize; m], q: usize, ask: [(usize, usize); q], } let w = std::mem::size_of::() * 8; let mut seg = vec![]; for i in 0..30 { seg.push(LazySegmentTree::build( a.iter().map(|a| (*a >> i & 1, 1)), n, Sol, )); } for (i, (s, q)) in ask.into_iter().enumerate() { let mut y = i + 1; for j in 1..=q { let z = (s + j) % m + 1; let u = (l[z - 1] ^ y).max(1).min(n); let v = (r[z - 1] ^ y).max(1).min(n); let U = (L[z - 1] ^ y).max(1).min(n); let V = (R[z - 1] ^ y).max(1).min(n); let (l, r) = (u.min(v) - 1, u.max(v)); let (L, R) = (U.min(V) - 1, U.max(V)); let v = x[z - 1] ^ y; let mut sum = 0; for (i, seg) in seg.iter_mut().enumerate() { if z & 1 == 0 && v >> i & 1 == 1 { seg.update(l, r, 1); } if z & 1 == 1 && v >> i & 1 == 0 { seg.update(l, r, 0); } sum += seg.find(L, R).0 << i; } y = (sum % (1 << 30)) as usize; } println!("{}", y); for s in seg.iter_mut() { s.rollback(); } } } struct Sol; impl TE for Sol { type T = (u32, u32); type E = i32; fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T { (l.0 + r.0, l.1 + r.1) } fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T { if *f == -1 { *x } else if *f == 0 { (0, x.1) } else { (x.1, x.1) } } fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E { if *h != -1 { *h } else { *g } } fn e(&self) -> Self::T { (0, 0) } fn id(&self) -> Self::E { -1 } } fn main() { run(); } // 問題が読めん // 区間or,and 区間和をonlineで処理して // というのを複数個のパターンについて解いて // 一つについて解くだけならbeatsでいい // 毎回やると均しが破綻 // 欲しいのは和だし30個セグ木もって遅延伝搬すれば解けてはいる // メモリが大変なことになってるが? // 64個ずつ管理? // rollback でメモリが大変にならないか? // いやq_i <= 10^3 だった、なんとかなるか // ---------- 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 ---------- // ---------- begin Lazy Segment Tree ---------- pub trait TE { type T: Copy; type E: Copy; fn fold(&self, l: &Self::T, r: &Self::T) -> Self::T; fn eval(&self, x: &Self::T, f: &Self::E) -> Self::T; fn merge(&self, g: &Self::E, h: &Self::E) -> Self::E; fn e(&self) -> Self::T; fn id(&self) -> Self::E; } pub struct LazySegmentTree { n: usize, size: usize, bit: u32, op: R, data: Vec<(R::T, R::E)>, memo: Vec<(usize, (R::T, R::E))>, } impl LazySegmentTree { pub fn new(n: usize, op: R) -> Self { assert!(n > 0); let size = n.next_power_of_two(); let bit = size.trailing_zeros(); let data = vec![(op.e(), op.id()); 2 * size]; Self { n, size, bit, op, data, memo: vec![], } } pub fn build(init: I, n: usize, op: R) -> Self where I: Iterator, { let mut seg = Self::new(n, op); for (data, ini) in seg.data[seg.size..].iter_mut().zip(init) { data.0 = ini; } for i in (1..seg.size).rev() { seg.pull(i); } seg.memo.clear(); seg } pub fn update(&mut self, l: usize, r: usize, f: R::E) { assert!(l <= r && r <= self.n); if l == r { return; } self.push_range(l, r); let mut s = l + self.size; let mut t = r + self.size; while s < t { if s & 1 == 1 { self.apply(s, &f); s += 1; } if t & 1 == 1 { t -= 1; self.apply(t, &f); } s >>= 1; t >>= 1; } let l = l + self.size; let r = r + self.size; for k in 1..=self.bit { if (l >> k) << k != l { self.pull(l >> k); } if (r >> k) << k != r { self.pull((r - 1) >> k); } } } pub fn find(&mut self, l: usize, r: usize) -> R::T { assert!(l <= r && r <= self.n); if l == r { return self.op.e(); } self.push_range(l, r); let mut l = l + self.size; let mut r = r + self.size; let mut p = self.op.e(); let mut q = self.op.e(); while l < r { if l & 1 == 1 { p = self.op.fold(&p, &self.data[l].0); l += 1; } if r & 1 == 1 { r -= 1; q = self.op.fold(&self.data[r].0, &q); } l >>= 1; r >>= 1; } self.op.fold(&p, &q) } pub fn set_at(&mut self, x: usize, v: R::T) { assert!(x < self.n); let x = x + self.size; for k in (1..=self.bit).rev() { self.push(x >> k); } self.memo.push((x, self.data[x])); self.data[x].0 = v; for k in 1..=self.bit { self.pull(x >> k); } } /* pub fn max_right

(&mut self, l: usize, f: P) -> usize where P: Fn(&R::T) -> bool, { assert!(l <= self.n); assert!(f(&self.op.e())); if l == self.n { return self.n; } self.push_range(l, self.n); let mut l = l + self.size; let mut sum = self.op.e(); while { l >>= l.trailing_zeros(); let v = self.op.fold(&sum, &self.data[l].0); if !f(&v) { while l < self.size { self.push(l); l <<= 1; let v = self.op.fold(&sum, &self.data[l].0); if f(&v) { sum = v; l += 1; } } return l - self.size; } sum = v; l += 1; l.count_ones() > 1 } {} self.n } pub fn min_left

(&mut self, r: usize, f: P) -> usize where P: Fn(&R::T) -> bool, { assert!(r <= self.n); assert!(f(&self.op.e())); if r == 0 { return 0; } self.push_range(0, r); let mut r = r + self.size; let mut sum = self.op.e(); while { r -= 1; while r > 1 && r & 1 == 1 { r >>= 1; } let v = self.op.fold(&self.data[r].0, &sum); if !f(&v) { while r < self.size { self.push(r); r = 2 * r + 1; let v = self.op.fold(&self.data[r].0, &sum); if f(&v) { sum = v; r -= 1; } } return r + 1 - self.size; } sum = v; (r & (!r + 1)) != r } {} 0 } */ fn push_range(&mut self, l: usize, r: usize) { let l = l + self.size; let r = r + self.size; for k in (1..(self.bit + 1)).rev() { if (l >> k) << k != l { self.push(l >> k); } if (r >> k) << k != r { self.push((r - 1) >> k); } } } fn apply(&mut self, x: usize, f: &R::E) { self.memo.push((x, self.data[x])); self.data[x].0 = self.op.eval(&self.data[x].0, f); self.data[x].1 = self.op.merge(&self.data[x].1, f); } fn push(&mut self, x: usize) { self.memo.push((x, self.data[x])); let f = std::mem::replace(&mut self.data[x].1, self.op.id()); self.apply(2 * x, &f); self.apply(2 * x + 1, &f); } fn pull(&mut self, x: usize) { self.memo.push((x, self.data[x])); self.data[x].0 = self.op.fold(&self.data[2 * x].0, &self.data[2 * x + 1].0); } pub fn rollback(&mut self) { let mut memo = std::mem::take(&mut self.memo); for (x, v) in memo.drain(..).rev() { self.data[x] = v; } self.memo = memo; } } // ---------- end Lazy Segment Tree ----------