XOR to the Max

Tree Vibees - XORing to the Max

Problem Statement

You’re given a tree with n nodes numbered from 0 to n - 1, and a 0-indexed array nums where nums[i] is the value of the i-th node. You’re also given a positive integer k.

You can perform the following operation any number of times:

  • Pick an edge [u, v] and set:

    • nums[u] = nums[u] ^ k

    • nums[v] = nums[v] ^ k

Return the maximum possible sum of all nums[i] after performing any number of such operations.

Example:

Input: nums = [1,2,1], k = 3, edges = [[0,1],[0,2]] Output: 6 Explanation: Choose edge [0,2]: nums becomes [2,2,2] => sum = 6

Best Data Structure for Solving the Problem

This is a classic greedy XOR game on a tree. Since any edge can be used, and operations are reversible, the tree structure becomes less important here. So no need to traverse the tree!

  • We mainly need: Arrays and bitwise operations.

  • Optional but interview-valuable: Dynamic Programming on Trees (for variations).

Multiple Approaches

Approach 1: Greedy Bitwise XOR Strategy 

Idea:
Every node can be XORed with k. The decision is whether doing so increases the sum.
BUT: Since operations are done in pairs (edge involves 2 nodes), the total number of XOR operations must be even.

If the number of beneficial XORs is even: Do them all.
If odd: Do all but the least beneficial one.

class Solution { public long maximumValueSum(int[] nums, int k, int[][] edges) { long maxSum = 0; int changedCount = 0; int minChangeDiff = Integer.MAX_VALUE; for (int num : nums) { int xorVal = num ^ k; maxSum += Math.max(num, xorVal); if (xorVal > num) changedCount++; minChangeDiff = Math.min(minChangeDiff, Math.abs(num - xorVal)); } return (changedCount % 2 == 0) ? maxSum : maxSum - minChangeDiff; } }

Approach 2: DFS + Dynamic Programming on Tree (More Theoretical)

Idea:
If the problem was about paths or subtrees, we could use DP on trees. But here it's not necessary.
Still, it's good to mention this for completeness in interviews.


import java.util.*;

class Solution {

    List<List<Integer>> graph;

    int[] nums;

    int k;

    public long maximumValueSum(int[] nums, int k, int[][] edges) {

        this.nums = nums;

        this.k = k;

        int n = nums.length;

        graph = new ArrayList<>();

        for (int i = 0; i < n; i++) graph.add(new ArrayList<>());

        for (int[] edge : edges) {

            graph.get(edge[0]).add(edge[1]);

            graph.get(edge[1]).add(edge[0]);

        }

        long[][] dp = new long[n][2];

        dfs(0, -1, dp);

        return Math.max(dp[0][0], dp[0][1]);

    }


    private void dfs(int node, int parent, long[][] dp) {

        dp[node][0] = nums[node];

        dp[node][1] = nums[node] ^ k;

        for (int child : graph.get(node)) {

            if (child == parent) continue;

            dfs(child, node, dp);

            dp[node][0] += Math.max(dp[child][0], dp[child][1]);

            dp[node][1] += Math.max(dp[child][0], dp[child][1]);

        }

    }

    public static void main(String[] args) {

        Solution sol = new Solution();

        int[] nums = {1, 2, 1};

        int k = 3;

        int[][] edges = {{0,1}, {0,2}};

        System.out.println(sol.maximumValueSum(nums, k, edges));

    }

}

⚠️ Common Mistakes and Pitfalls

  • Assuming you have to traverse the tree — you don’t!

  • Forgetting the operation is on pairs → total XOR ops must be even

  • Ignoring the case where skipping one less beneficial XOR increases the overall sum

  • Misunderstanding bitwise XOR behavior: a ^ k can be smaller or larger than a

📊 Time and Space Complexity Analysis

Step         Time Complexity        Space Complexity
Greedy XOR approach            O(n)            O(1)
Tree building (unused)            O(n)            O(n)

Where n = number of nodes

🌍 Real-World Applications

  • Encryption toggles (XOR is commonly used)

  • Bitmasking problems in scheduling, resource allocation

  • XOR-swap logic in systems with limited memory

  • Graph operations optimization


I hope you found this article insightful! Keep exploring, keep learning, and don’t forget to check back daily for more exciting problem breakdowns. If you know someone who would benefit from this, share it with them and help them grow too! That’s it for today—see you in the next post!

                                                                                                                                         Signing off!! 

                                                                                                Master DSA One Problem at a Time :)

Comments

Popular posts from this blog

Divisible Drama — Who’s In, Who’s Out?

Trailing Zeros in Factorial – How Many and Why?

Minimum equal sum