#1787
Hard Algorithms Make the xor of all segments equal to zero
Array Hash Table Dynamic Programming Bit Manipulation Counting
41.0% acceptance
Mar 1, 2026
424
27
You are given an array nums and an integer k. Return the minimum number of elements to change so that the XOR of all segments of size k equals zero.
Solution
Rust
Time O(n * m)
Space O(n * m)
impl Solution {
pub fn min_changes(nums: Vec<i32>, k: i32) -> i32 {
let n = nums.len();
let k = k as usize;
let max_val = 1024usize;
// Group nums by index mod k
let mut groups: Vec<Vec<i32>> = vec![vec![]; k];
for (i, &v) in nums.iter().enumerate() {
groups[i % k].push(v);
}
// dp[x] = min changes to make XOR of chosen values for groups 0..i equal x
let mut dp = vec![n as i32; max_val];
dp[0] = 0;
for group in &groups {
let group_size = group.len() as i32;
let mut freq = vec![0i32; max_val];
for &v in group {
freq[v as usize] += 1;
}
// Only iterate over values that actually appear in this group.
// Complexity per group: O(max_val * distinct_vals) instead of O(max_val^2).
let distinct: Vec<(usize, i32)> = (0..max_val)
.filter(|&v| freq[v] > 0)
.map(|v| (v, freq[v]))
.collect();
let global_min = *dp.iter().min().unwrap();
let base = global_min + group_size;
let prev_dp = dp.clone();
dp = vec![base; max_val];
for prev_x in 0..max_val {
// Skip if no transition from prev_x can beat the base cost.
if prev_dp[prev_x] >= base { continue; }
for &(v, fv) in &distinct {
let new_x = prev_x ^ v;
let cost = prev_dp[prev_x] + group_size - fv;
if cost < dp[new_x] {
dp[new_x] = cost;
}
}
}
}
dp[0]
}
}