sashimingの競プロメモ

チラシの裏

ABC121 D - XOR World メモ

XORの性質とか知らないのでアでした、あと D 解けてる人多くてビックリ

問題概要

A 以上 B 以下の全ての整数の XOR 和を求めよ。

  • 制約:0 \leq A \leq B \leq 10^{12}

問題リンクは こちら から

解説

ここからは NM の XOR を  N \oplus M で表すことにします。

言い換え

XOR の性質として、

  • 同じ数の XOR は0 A \oplus A = 0

があります。

問題上の f(A, B) は、この性質を用いれば

 f(A, B) = f(0,B) \oplus f(0,A-1)

これは 0 以上 A-1 以下の部分で数がダブり、その部分における XOR 和が 0 になるからです。

よって、A から B までの XOR 和は、 0 から A-1 までの XOR 和と 0 から B までの XOR 和の XOR と等しくなります。

0からXまでのXOR和を求める

以上のことから、0 から A-1 までの XOR 和と 0 から B までの XOR 和さえ求めればよいです。

ここで実験。適当に x=0,1,\cdots,15f(0,x) を求めると

 x    bin    f(0,x)
-------------------
 0    0000    0000
 1    0001    0001
 2    0010    0011
 3    0011    0000

 4    0100    0100
 5    0101    0001
 6    0110    0111
 7    0111    0000

 8    1000    1000
 9    1001    0001
10    1010    1011
11    1011    0000

12    1100    1100
13    1101    0001
14    1110    1111
15    1111    0000

実験より、 x \% 4

  • 0 のとき:f(0,x) = x
  • 1 のとき:f(0,x) = 1
  • 2 のとき:f(0,x) = x+1
  • 3 のとき:f(0,x) = 0

となります。これで f(0,x) が求められるようになったので、この問題は解けました。

ソースコード

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int main(void){
    ll a, b; cin >> a >> b; a--;
    ll xa, xb;
    if(a % 4 == 0) xa = a;
    else if(a % 4 == 1) xa = 1;
    else if(a % 4 == 2) xa = a+1;
    else xa = 0;

    if(b % 4 == 0) xb = b;
    else if(b % 4 == 1) xb = 1;
    else if(b % 4 == 2) xb = b+1;
    else xb = 0;

    cout << (ll)(xa^xb) << endl;

    return 0;
}