C++でビット単位XORが奇数になるペアを数える方法
整数型の配列が与えられたとき、その配列の要素から組み合わせられるすべてのペアの中で、ビット単位XOR(排他的論理和)を計算した結果が奇数となるペアの総数を求めるのがこの問題の目的です。
XOR演算の真理値表
まずは、XOR演算の基本的な挙動を真理値表で確認しましょう。
| A | B | A XOR B |
| 0 | 0 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 1 | 0 |
この表からわかるように、XORの結果が1(奇数)になるのは、2つの値のうち片方だけが1(奇数)である場合です。言い換えると、「偶数と奇数」の組み合わせでのみXORは奇数になり、偶数同士や奇数同士の組み合わせでは必ず偶数になります。
入力例と出力例
- 入力 − int arr[] = {2, 8, 1, 5, 11}
- 出力 − XORが奇数になるペアの総数:6
全ペアの検証
| a1 | a2 | a1 XOR a2 |
| 2 | 8 | 10 |
| 2 | 1 | 3 |
| 2 | 5 | 7 |
| 2 | 11 | 9 |
| 8 | 1 | 9 |
| 8 | 5 | 13 |
| 8 | 11 | 3 |
| 1 | 5 | 4 |
| 1 | 11 | 10 |
| 5 | 11 | 14 |
上記の10通りの組み合わせのうち、XORの結果が奇数(3、7、9、9、13、3)になっているのは6通りです。これは、配列中の偶数(2、8)が2個、奇数(1、5、11)が3個あるため、「2 × 3 = 6」という計算結果と一致します。
プログラムで使用するアプローチ
すべてのペアを実際に計算するとO(n²)の時間がかかりますが、前述の性質を利用すれば、偶数の個数を数えるだけで答えをO(n)で求められます。手順は以下のとおりです。
- 整数要素の配列を入力として受け取り、ペアを形成できるようにします。
- 配列のサイズを計算し、後続の処理のためにデータを関数へ渡します。
- 偶数の個数を格納するための一時変数countを用意します。
- iを0から配列サイズまでループさせ、各要素が偶数(arr[i] % 2 == 0)であればcountをインクリメントします。
- 奇数の個数は「size - count」で求められるため、XORが奇数になるペアの総数は count * (size - count) で計算できます。
- 結果を返して出力します。
C++実装例
#include <iostream>
using namespace std;
//XORが奇数になるペアを数える
int XOR_Odd(int arr[], int size){
int count = 0;
for (int i = 0; i < size; i++){
if (arr[i] % 2 == 0){
count++;
}
}
int odd = count * (size-count);
return odd;
}
int main(){
int arr[] = { 6, 1, 3, 4, 8, 9};
int size = sizeof(arr) / sizeof(arr[0]);
cout<<"XORが奇数になるペアの総数: "<<XOR_Odd(arr, size);
return 0;
}
出力結果
上記のコードを実行すると、次の出力が得られます。
XORが奇数になるペアの総数: 9
この配列{6, 1, 3, 4, 8, 9}には偶数が3個(6、4、8)、奇数が3個(1、3、9)含まれているため、3 × 3 = 9という結果になります。全ペアを総当たりで調べる必要がないため、配列のサイズが大きくなっても高速に処理できる点がこの手法の大きな利点です。
-
C++で指定されたXOR値を持つペアの数を効率的にカウントする方法
このチュートリアルでは、配列の中から指定されたXOR値を持つペアの数を求めるプログラムについて解説します。具体的には、整数の配列とターゲットとなる値が与えられ、その2つの要素のXOR(排他的論理和)がターゲット値と一致するペアがいくつ存在するかをカウントするのが課題です。アルゴリズムの考え方全てのペアを総当たりで調べる方法(O(n²))もありますが、ここではハッシュマップ(unordered_map)を活用することで、時間計算量O(n)で効率的に解く手法を紹介します。基本的なアイデアは以下の通りです。XORの性質を利用します。ある要素 a に対して「a ^ b = x」が成り立つとき、「b =
-
C++で二分木の隣接ノードのうちXORが奇数になるペアを数える方法
このチュートリアルでは、二分木においてXOR(排他的論理和)が奇数になる隣接ノードのペアの数を求めるプログラムについて解説します。 隣接ノードとは、親ノードとその直接の子ノードの組み合わせを指します。与えられた二分木に対して、隣接する2つの要素のXOR値が奇数になるペアがいくつあるかを数えるのが今回のタスクです。 XORが奇数になる条件 まず押さえておきたい重要な性質として、XORの結果が奇数になるのは、2つの値のうち片方が奇数でもう片方が偶数の場合だけです。同じ偶奇(パリティ)を持つ2つの値のXORは必ず偶数になります。 奇数 XOR 偶数 → 奇数 奇数 XOR 奇数 → 偶数 偶数 X