AtCoder Beginner Contest 185 F – Range Xor Query をPython3で解く

Share

AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。

出典:
AtCoder Beginner Contest 185 F – Range Xor Query

値の書き換えを伴う範囲参照。フェニック木やセグメント木など、特定の構造を知らないと解けない問題だ。

# AtCoder Beginner Contest 185 F - Range Xor Query
# https://atcoder.jp/contests/abc185/tasks/abc185_f
# tag: ビット操作 範囲参照 フェニック木 セグメント木 基礎問題 典型問題

# xor はビットの反転操作。
# 仮に Ti = 1 の時の操作、すなわち値の書き換えが
# なかった場合には、xor の一種の累積和が分かっていれば
# 簡単に解くことができる。

# 逆に言うと、値の書き換えがある場合には、単純な累積和で
# 解くことができない。
# フェニック木(Binary Indexed Tree)、
# あるいはセグメント木を
# 用いる必要がある。

# ここでは、実装の簡単な BIT で解いてみる。
def main():
N, Q = map(int, input().split())
A = list(map(int, input().split()))
queries = [list(map(int, input().split())) for _ in range(Q)]

# Binary Indexed Tree (1-indexed)
bitree = [0] * (N+1)
def get_csum(x):
result = 0
while x:
result ^= bitree[x]
x -= x & -x
return result

def op_xor(x, y):
while x <= N:
bitree[x] ^= y
x += x & -x

# BIT 初期化
for i, a in enumerate(A, start=1):
op_xor(i, a)

# クエリ処理
for t, x, y in queries:
if t == 1:
op_xor(x, y)
else:
print(get_csum(y) ^ get_csum(x-1))

main()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です