#!/usr/bin/env python3 from array import array import sys BITS = 30 VALUE_MASK = (1 << BITS) - 1 LOW15_MASK = (1 << 15) - 1 _BIT_POS_LO = tuple(tuple(b for b in range(15) if mask & (1 << b)) for mask in range(1 << 15)) _BIT_POS_HI = tuple(tuple(b + 15 for b in bits) for bits in _BIT_POS_LO) def parse_input(): data = sys.stdin.buffer.read() if not data or data[-1] > 32: data += b"\0" i = 0 while data[i] <= 32: i += 1 n = 0 while data[i] > 32: n = n * 10 + data[i] - 48 i += 1 while data[i] <= 32: i += 1 m = 0 while data[i] > 32: m = m * 10 + data[i] - 48 i += 1 def read_array(length, leading_zero=False, data=data): nonlocal i out = array("I", [0]) * (length + leading_zero) j = 1 if leading_zero else 0 end = j + length while j < end: while data[i] <= 32: i += 1 value = 0 while data[i] > 32: value = value * 10 + data[i] - 48 i += 1 out[j] = value j += 1 return out initial = read_array(n) left_data = read_array(m, True) right_data = read_array(m, True) mask_data = read_array(m, True) sum_left_data = read_array(m, True) sum_right_data = read_array(m, True) while data[i] <= 32: i += 1 problem_count = 0 while data[i] > 32: problem_count = problem_count * 10 + data[i] - 48 i += 1 starts = array("I", [0]) * problem_count counts = array("I", [0]) * problem_count k = 0 while k < problem_count: while data[i] <= 32: i += 1 value = 0 while data[i] > 32: value = value * 10 + data[i] - 48 i += 1 starts[k] = value while data[i] <= 32: i += 1 value = 0 while data[i] > 32: value = value * 10 + data[i] - 48 i += 1 counts[k] = value k += 1 return (n, m, initial, left_data, right_data, mask_data, sum_left_data, sum_right_data, problem_count, starts, counts) def build_tree(values): n = len(values) size = 1 while size < n: size <<= 1 nodes = size << 1 total = array("Q", [0]) * nodes counts = array("I", [0]) * (nodes * BITS) any_bits = array("I", [0]) * nodes all_bits = array("I", [0]) * nodes lazy_and = array("I", [VALUE_MASK]) * nodes lazy_or = array("I", [0]) * nodes saved = bytearray(nodes) base = size bit_pos_lo = _BIT_POS_LO bit_pos_hi = _BIT_POS_HI low15 = LOW15_MASK for i, value in enumerate(values): p = base + i total[p] = value any_bits[p] = value all_bits[p] = value count_base = p * 30 for b in bit_pos_lo[value & low15]: counts[count_base + b] = 1 for b in bit_pos_hi[value >> 15]: counts[count_base + b] = 1 for p in range(size - 1, 0, -1): left = p << 1 right = left | 1 total[p] = total[left] + total[right] any_bits[p] = any_bits[left] | any_bits[right] all_bits[p] = all_bits[left] & all_bits[right] count_base = p * 30 left_base = left * 30 right_base = right * 30 for b in range(30): counts[count_base + b] = counts[left_base + b] + counts[right_base + b] history = [] history_append = history.append def save_full(p, total=total, counts=counts, any_bits=any_bits, all_bits=all_bits, lazy_and=lazy_and, lazy_or=lazy_or, saved=saved, history_append=history_append): saved[p] = 1 count_base = p * 30 history_append((p, total[p], any_bits[p], all_bits[p], lazy_and[p], lazy_or[p], counts[count_base:count_base + 30])) def push_nonidentity(p, half, parent_and, parent_or, total=total, counts=counts, any_bits=any_bits, all_bits=all_bits, lazy_and=lazy_and, lazy_or=lazy_or, saved=saved, bit_pos_lo=bit_pos_lo, bit_pos_hi=bit_pos_hi, low15=low15, save_full=save_full): child = p << 1 count_base = child * 30 child_and = lazy_and[child] child_or = lazy_or[child] new_and = (child_and & parent_and) | parent_or new_or = (child_or & parent_and) | parent_or old_any = any_bits[child] old_all = all_bits[child] clear_bits = old_any & (VALUE_MASK ^ parent_and) set_bits = parent_or & (VALUE_MASK ^ old_all) changed = clear_bits | set_bits if changed or new_and != child_and or new_or != child_or: if not saved[child]: save_full(child) value = total[child] for b in bit_pos_lo[clear_bits & low15]: index = count_base + b value -= counts[index] << b counts[index] = 0 for b in bit_pos_hi[clear_bits >> 15]: index = count_base + b value -= counts[index] << b counts[index] = 0 for b in bit_pos_lo[set_bits & low15]: index = count_base + b old_count = counts[index] value += (half - old_count) << b counts[index] = half for b in bit_pos_hi[set_bits >> 15]: index = count_base + b old_count = counts[index] value += (half - old_count) << b counts[index] = half total[child] = value any_bits[child] = (old_any & parent_and) | parent_or all_bits[child] = (old_all & parent_and) | parent_or lazy_and[child] = new_and lazy_or[child] = new_or child = (p << 1) | 1 count_base = child * 30 child_and = lazy_and[child] child_or = lazy_or[child] new_and = (child_and & parent_and) | parent_or new_or = (child_or & parent_and) | parent_or old_any = any_bits[child] old_all = all_bits[child] clear_bits = old_any & (VALUE_MASK ^ parent_and) set_bits = parent_or & (VALUE_MASK ^ old_all) changed = clear_bits | set_bits if changed or new_and != child_and or new_or != child_or: if not saved[child]: save_full(child) value = total[child] for b in bit_pos_lo[clear_bits & low15]: index = count_base + b value -= counts[index] << b counts[index] = 0 for b in bit_pos_hi[clear_bits >> 15]: index = count_base + b value -= counts[index] << b counts[index] = 0 for b in bit_pos_lo[set_bits & low15]: index = count_base + b old_count = counts[index] value += (half - old_count) << b counts[index] = half for b in bit_pos_hi[set_bits >> 15]: index = count_base + b old_count = counts[index] value += (half - old_count) << b counts[index] = half total[child] = value any_bits[child] = (old_any & parent_and) | parent_or all_bits[child] = (old_all & parent_and) | parent_or lazy_and[child] = new_and lazy_or[child] = new_or lazy_and[p] = VALUE_MASK lazy_or[p] = 0 def range_and(p, left_bound, length, query_left, query_right, mask, total=total, counts=counts, any_bits=any_bits, all_bits=all_bits, lazy_and=lazy_and, lazy_or=lazy_or, saved=saved, bit_pos_lo=bit_pos_lo, bit_pos_hi=bit_pos_hi, low15=low15, push_nonidentity=push_nonidentity, save_full=save_full): if query_left <= left_bound and left_bound + length <= query_right: changed = any_bits[p] & (VALUE_MASK ^ mask) if not changed: return 0 if not saved[p]: save_full(p) value = total[p] count_base = p * 30 for b in bit_pos_lo[changed & low15]: index = count_base + b value -= counts[index] << b counts[index] = 0 for b in bit_pos_hi[changed >> 15]: index = count_base + b value -= counts[index] << b counts[index] = 0 total[p] = value any_bits[p] &= mask all_bits[p] &= mask lazy_and[p] &= mask lazy_or[p] &= mask return changed half = length >> 1 parent_and = lazy_and[p] parent_or = lazy_or[p] if parent_and != VALUE_MASK or parent_or: push_nonidentity(p, half, parent_and, parent_or) middle = left_bound + half if query_right <= middle: changed = range_and(p << 1, left_bound, half, query_left, query_right, mask) elif query_left >= middle: changed = range_and(p << 1 | 1, middle, half, query_left, query_right, mask) else: changed = range_and(p << 1, left_bound, half, query_left, query_right, mask) changed |= range_and(p << 1 | 1, middle, half, query_left, query_right, mask) if changed: if not saved[p]: save_full(p) left = p << 1 right = left | 1 count_base = p * 30 left_base = left * 30 right_base = right * 30 for b in bit_pos_lo[changed & low15]: counts[count_base + b] = counts[left_base + b] + counts[right_base + b] for b in bit_pos_hi[changed >> 15]: counts[count_base + b] = counts[left_base + b] + counts[right_base + b] total[p] = total[left] + total[right] any_bits[p] = any_bits[left] | any_bits[right] all_bits[p] = all_bits[left] & all_bits[right] return changed def range_or(p, left_bound, length, query_left, query_right, mask, total=total, counts=counts, any_bits=any_bits, all_bits=all_bits, lazy_and=lazy_and, lazy_or=lazy_or, saved=saved, bit_pos_lo=bit_pos_lo, bit_pos_hi=bit_pos_hi, low15=low15, push_nonidentity=push_nonidentity, save_full=save_full): if query_left <= left_bound and left_bound + length <= query_right: changed = mask & (VALUE_MASK ^ all_bits[p]) if not changed: return 0 if not saved[p]: save_full(p) value = total[p] count_base = p * 30 for b in bit_pos_lo[changed & low15]: index = count_base + b old_count = counts[index] value += (length - old_count) << b counts[index] = length for b in bit_pos_hi[changed >> 15]: index = count_base + b old_count = counts[index] value += (length - old_count) << b counts[index] = length total[p] = value any_bits[p] |= mask all_bits[p] |= mask lazy_and[p] |= mask lazy_or[p] |= mask return changed half = length >> 1 parent_and = lazy_and[p] parent_or = lazy_or[p] if parent_and != VALUE_MASK or parent_or: push_nonidentity(p, half, parent_and, parent_or) middle = left_bound + half if query_right <= middle: changed = range_or(p << 1, left_bound, half, query_left, query_right, mask) elif query_left >= middle: changed = range_or(p << 1 | 1, middle, half, query_left, query_right, mask) else: changed = range_or(p << 1, left_bound, half, query_left, query_right, mask) changed |= range_or(p << 1 | 1, middle, half, query_left, query_right, mask) if changed: if not saved[p]: save_full(p) left = p << 1 right = left | 1 count_base = p * 30 left_base = left * 30 right_base = right * 30 for b in bit_pos_lo[changed & low15]: counts[count_base + b] = counts[left_base + b] + counts[right_base + b] for b in bit_pos_hi[changed >> 15]: counts[count_base + b] = counts[left_base + b] + counts[right_base + b] total[p] = total[left] + total[right] any_bits[p] = any_bits[left] | any_bits[right] all_bits[p] = all_bits[left] & all_bits[right] return changed def range_sum(p, left_bound, length, query_left, query_right, pending_and=VALUE_MASK, pending_or=0, total=total, counts=counts, any_bits=any_bits, all_bits=all_bits, lazy_and=lazy_and, lazy_or=lazy_or, bit_pos_lo=bit_pos_lo, bit_pos_hi=bit_pos_hi, low15=low15): if query_left <= left_bound and left_bound + length <= query_right: if pending_and == VALUE_MASK and pending_or == 0: return total[p] if pending_and == pending_or: return length * pending_or value = total[p] count_base = p * 30 clear_bits = any_bits[p] & (VALUE_MASK ^ pending_and) set_bits = pending_or & (VALUE_MASK ^ all_bits[p]) for b in bit_pos_lo[clear_bits & low15]: value -= counts[count_base + b] << b for b in bit_pos_hi[clear_bits >> 15]: value -= counts[count_base + b] << b for b in bit_pos_lo[set_bits & low15]: value += (length - counts[count_base + b]) << b for b in bit_pos_hi[set_bits >> 15]: value += (length - counts[count_base + b]) << b return value node_and = lazy_and[p] node_or = lazy_or[p] child_pending_and = (node_and & pending_and) | pending_or child_pending_or = (node_or & pending_and) | pending_or half = length >> 1 middle = left_bound + half if query_right <= middle: return range_sum(p << 1, left_bound, half, query_left, query_right, child_pending_and, child_pending_or) if query_left >= middle: return range_sum(p << 1 | 1, middle, half, query_left, query_right, child_pending_and, child_pending_or) return (range_sum(p << 1, left_bound, half, query_left, query_right, child_pending_and, child_pending_or) + range_sum(p << 1 | 1, middle, half, query_left, query_right, child_pending_and, child_pending_or)) def begin(): history.clear() def rollback(): for h in history: p = h[0] total[p] = h[1] any_bits[p] = h[2] all_bits[p] = h[3] lazy_and[p] = h[4] lazy_or[p] = h[5] count_base = p * 30 counts[count_base:count_base + 30] = h[6] saved[p] = 0 history.clear() return size, begin, rollback, range_and, range_or, range_sum def main(): (n, m, initial, left_data, right_data, mask_data, sum_left_data, sum_right_data, problem_count, starts, query_counts) = parse_input() size, begin, rollback, range_and, range_or, range_sum = build_tree(initial) output = [] output_append = output.append write = sys.stdout.write problem_index = 0 while problem_index < problem_count: begin() y = problem_index + 1 query_count = query_counts[problem_index] z = ((starts[problem_index] + 1) % m) + 1 while query_count: u = left_data[z] ^ y if u < 1: u = 1 elif u > n: u = n v = right_data[z] ^ y if v < 1: v = 1 elif v > n: v = n if u <= v: update_left = u - 1 update_right = v else: update_left = v - 1 update_right = u u = sum_left_data[z] ^ y if u < 1: u = 1 elif u > n: u = n v = sum_right_data[z] ^ y if v < 1: v = 1 elif v > n: v = n if u <= v: sum_left = u - 1 sum_right = v else: sum_left = v - 1 sum_right = u update_mask = (mask_data[z] ^ y) & VALUE_MASK if z & 1: range_and(1, 0, size, update_left, update_right, update_mask) else: range_or(1, 0, size, update_left, update_right, update_mask) y = range_sum(1, 0, size, sum_left, sum_right) & VALUE_MASK z += 1 if z > m: z = 1 query_count -= 1 output_append(str(y)) rollback() if len(output) == 4096: write("\n".join(output) + "\n") output.clear() problem_index += 1 if output: write("\n".join(output) + "\n") if __name__ == "__main__": main()