ARMERIA

Rubyと競技プログラミングの話 AtCoderやCodeforcesの問題解説記事が多め。

ABC121 D - XOR World

D - XOR World

解法

 A, A+1, ..., B について○○を計算した合計を求めよ」という問題で使える実装テクニックとして、代わりに「 0, 1, ..., B について○○を計算した合計」から「 0, 1, ..., A-1 のうち○○を計算した合計」を引いたものを求めると考えると、変数が減る上に同じ処理を2回すれば良いだけになるので楽です。XORの場合は、引き算としてはXORをすればよいです。

そのため以降は  0, 1, ..., B のXORを考えます。このとき0から数えて、各ビットの値は以下のようになっています。

f:id:betrue12:20190309224118p:plain

XORを求めたいので、重要なのは各ビットごとの1の個数の偶奇です。

図を見るとまず一番下以外のビットについては、隣り合う (偶数, 奇数) のペアではビット値が同じになっていることが分かります。つまり一番下以外の各ビットについて、このペアに含まれる1の個数は偶数個です。

一番下のビットだけはそうなっていませんが、隣り合う4つごとに区切って考えると1つの4つ組には1が2個あることが分かります。

つまり左から4つ組で区切っていくと、その4つの中では必ず全てのビットについて1の個数が偶数個になっている、つまり4つの数のXORがちょうど0になることが分かります。

f:id:betrue12:20190309224128p:plain

そのため4つ組ができているところは無視してもよく、一番最後に余ったところだけを計算すればよいです。具体的には  B を含む4つ組の最初の数字は  \lfloor\frac{B}{4}\rfloor\times 4 になるので、この値から  B までのXORを取ればよいです。

この計算を  A-1 B の両方に行い、その結果のXORを取ったものが答えです。

ACコード