Pattern Reference
XOR Basis / Linear Basis
"Basis of numbers under XOR. Maximum XOR subset, minimum XOR subset, K-th smallest XOR, rank of XOR space."
Loading...
Deep Dive Tutorial
An XOR linear basis stores at most 30-60 numbers (one per bit) such that any XOR combination of the original array equals some XOR combination of basis elements. Insert: for each number, try to reduce it using existing basis elements from high bit to low. If it reduces to 0, it's linearly dependent (already representable). If not, add it at its highest bit position.
XOR linear basis template
class XorBasis {
constructor() { this.basis = new Array(30).fill(0); this.size = 0; }
insert(x) {
for (let i = 29; i >= 0; i--) {
if (!((x >> i) & 1)) continue; // bit i not set
if (!this.basis[i]) { this.basis[i] = x; this.size++; return true; }
x ^= this.basis[i]; // reduce by existing basis element
}
return false; // x was 0 after reduction → linearly dependent
}
// Maximum XOR achievable using any subset
maxXor() {
let res = 0;
for (let i = 29; i >= 0; i--) res = Math.max(res, res ^ this.basis[i]);
return res;
}
// Minimum non-zero XOR achievable (lowest bit basis element)
minXor() {
for (let i = 0; i <= 29; i++) if (this.basis[i]) return this.basis[i];
return 0;
}
// k-th smallest XOR value (1-indexed, must reduce basis to row echelon form first)
// First reduce: for each i from low to high, reduce higher basis elements
kthSmallest(k) {
const reduced = [];
for (let i = 0; i <= 29; i++) {
if (!this.basis[i]) continue;
let v = this.basis[i];
for (let j = i - 1; j >= 0; j--) if ((v >> j) & 1) v ^= this.basis[j];
reduced.push(v);
}
// Now reduced[i] corresponds to bit i of k
let res = 0;
for (let i = 0; i < reduced.length; i++) if ((k >> i) & 1) res ^= reduced[i];
return res;
}
}Worked Problems
⊕
XOR basis key properties:
- At most 30 elements (one per bit for 32-bit integers)
- Spans the same XOR closure as the original set
- Any number representable as XOR of subset iff it reduces to 0 during insertion
Max XOR algorithm: Greedily try to set each bit from high to low: if XOR-ing with basis element increases current result, do it.
Count distinct XOR values: 2^(basis.size) distinct values possible (including 0).
Merge two bases: Insert all elements of one into the other — O(30²) per merge.
Online vs offline: Basis supports online insertions. For "max XOR with elements ≤ limit," sort and insert offline.
- At most 30 elements (one per bit for 32-bit integers)
- Spans the same XOR closure as the original set
- Any number representable as XOR of subset iff it reduces to 0 during insertion
Max XOR algorithm: Greedily try to set each bit from high to low: if XOR-ing with basis element increases current result, do it.
Count distinct XOR values: 2^(basis.size) distinct values possible (including 0).
Merge two bases: Insert all elements of one into the other — O(30²) per merge.
Online vs offline: Basis supports online insertions. For "max XOR with elements ≤ limit," sort and insert offline.