Count Triplets with Even XOR Set Bits II
MediumUpdated: Aug 2, 2025
Practice on:
Problem
Given three integer arrays a, b, and c, return the number of triplets
(a[i], b[j], c[k]), such that the bitwise XOR between the elements of each triplet has an even number of set bits.
Examples
Example 1:
Input: a = [1], b = [2], c = [3]
Output: 1
Explanation:
The only triplet is `(a[0], b[0], c[0])` and their `XOR` is: `1 XOR 2 XOR 3 =
002`.
Example 2:
Input: a = [1,1], b = [2,3], c = [1,5]
Output: 4
Explanation:
Consider these four triplets:
* `(a[0], b[1], c[0])`: `1 XOR 3 XOR 1 = 0112`
* `(a[1], b[1], c[0])`: `1 XOR 3 XOR 1 = 0112`
* `(a[0], b[0], c[1])`: `1 XOR 2 XOR 5 = 1102`
* `(a[1], b[0], c[1])`: `1 XOR 2 XOR 5 = 1102`
Constraints:
1 <= a.length, b.length, c.length <= 10^50 <= a[i], b[i], c[i] <= 10^9
Solution
Method 1 – Prefix XOR and Parity Counting
Intuition
For each triplet (a[i], b[j], c[k]), the XOR of the three numbers has an even number of set bits if the parity of set bits in a[i] ^ b[j] ^ c[k] is even. We can precompute the parity of set bits for all possible values and use prefix XOR and counting to efficiently count valid triplets.
Approach
- For each array, count how many numbers have even and odd set bits.
- For all combinations of parities (even/odd) for a, b, c, check if their XOR parity is even.
- Multiply the counts for valid combinations and sum them up.
Code
C++
class Solution {
public:
long long countTriplets(vector<int>& a, vector<int>& b, vector<int>& c) {
auto parity = [](int x) { return __builtin_popcount(x) % 2; };
long long cntA[2] = {}, cntB[2] = {}, cntC[2] = {};
for (int x : a) cntA[parity(x)]++;
for (int x : b) cntB[parity(x)]++;
for (int x : c) cntC[parity(x)]++;
long long ans = 0;
for (int pa = 0; pa < 2; ++pa)
for (int pb = 0; pb < 2; ++pb)
for (int pc = 0; pc < 2; ++pc)
if ((pa ^ pb ^ pc) == 0)
ans += cntA[pa] * cntB[pb] * cntC[pc];
return ans;
}
};
Go
func countTriplets(a, b, c []int) int64 {
parity := func(x int) int {
cnt := 0
for x > 0 {
cnt ^= x & 1
x >>= 1
}
return cnt
}
cntA, cntB, cntC := [2]int64{}, [2]int64{}, [2]int64{}
for _, x := range a {
cntA[parity(x)]++
}
for _, x := range b {
cntB[parity(x)]++
}
for _, x := range c {
cntC[parity(x)]++
}
var ans int64
for pa := 0; pa < 2; pa++ {
for pb := 0; pb < 2; pb++ {
for pc := 0; pc < 2; pc++ {
if pa^pb^pc == 0 {
ans += cntA[pa] * cntB[pb] * cntC[pc]
}
}
}
}
return ans
}
Java
class Solution {
public long countTriplets(int[] a, int[] b, int[] c) {
long[] cntA = new long[2], cntB = new long[2], cntC = new long[2];
for (int x : a) cntA[Integer.bitCount(x) % 2]++;
for (int x : b) cntB[Integer.bitCount(x) % 2]++;
for (int x : c) cntC[Integer.bitCount(x) % 2]++;
long ans = 0;
for (int pa = 0; pa < 2; pa++)
for (int pb = 0; pb < 2; pb++)
for (int pc = 0; pc < 2; pc++)
if ((pa ^ pb ^ pc) == 0)
ans += cntA[pa] * cntB[pb] * cntC[pc];
return ans;
}
}
Kotlin
class Solution {
fun countTriplets(a: IntArray, b: IntArray, c: IntArray): Long {
val cntA = LongArray(2)
val cntB = LongArray(2)
val cntC = LongArray(2)
for (x in a) cntA[Integer.bitCount(x) % 2]++
for (x in b) cntB[Integer.bitCount(x) % 2]++
for (x in c) cntC[Integer.bitCount(x) % 2]++
var ans = 0L
for (pa in 0..1)
for (pb in 0..1)
for (pc in 0..1)
if ((pa xor pb xor pc) == 0)
ans += cntA[pa] * cntB[pb] * cntC[pc]
return ans
}
}
Python
class Solution:
def countTriplets(self, a: list[int], b: list[int], c: list[int]) -> int:
def parity(x: int) -> int:
return bin(x).count('1') % 2
cntA = [0, 0]
cntB = [0, 0]
cntC = [0, 0]
for x in a:
cntA[parity(x)] += 1
for x in b:
cntB[parity(x)] += 1
for x in c:
cntC[parity(x)] += 1
ans = 0
for pa in range(2):
for pb in range(2):
for pc in range(2):
if pa ^ pb ^ pc == 0:
ans += cntA[pa] * cntB[pb] * cntC[pc]
return ans
Rust
impl Solution {
pub fn count_triplets(a: Vec<i32>, b: Vec<i32>, c: Vec<i32>) -> i64 {
let mut cnt_a = [0; 2];
let mut cnt_b = [0; 2];
let mut cnt_c = [0; 2];
for &x in &a {
cnt_a[x.count_ones() as usize % 2] += 1;
}
for &x in &b {
cnt_b[x.count_ones() as usize % 2] += 1;
}
for &x in &c {
cnt_c[x.count_ones() as usize % 2] += 1;
}
let mut ans = 0i64;
for pa in 0..2 {
for pb in 0..2 {
for pc in 0..2 {
if pa ^ pb ^ pc == 0 {
ans += cnt_a[pa] as i64 * cnt_b[pb] as i64 * cnt_c[pc] as i64;
}
}
}
}
ans
}
}
TypeScript
class Solution {
countTriplets(a: number[], b: number[], c: number[]): number {
const parity = (x: number) => x.toString(2).split('1').length % 2
const cntA = [0, 0], cntB = [0, 0], cntC = [0, 0]
for (const x of a) cntA[parity(x)]++
for (const x of b) cntB[parity(x)]++
for (const x of c) cntC[parity(x)]++
let ans = 0n
for (let pa = 0; pa < 2; ++pa)
for (let pb = 0; pb < 2; ++pb)
for (let pc = 0; pc < 2; ++pc)
if ((pa ^ pb ^ pc) === 0)
ans += BigInt(cntA[pa]) * BigInt(cntB[pb]) * BigInt(cntC[pc])
return Number(ans)
}
}
Complexity
- ⏰ Time complexity:
O(n + m + l)where n, m, l are the lengths of a, b, c (single pass through each array). - 🧺 Space complexity:
O(1)for counters.