BackmediumTreesUberPaytm

Bitmask Subset Energy Evaluator 4 Solution

Problem Statement

You are given a rooted tree with N nodes numbered from 1 to N. Each node i carries an integer value a[i] (0 ≤ a[i] < 2^20). For any two distinct nodes u and v, let the path energy E(u, v) be the bitwise AND of the values of all nodes that lie on the unique simple path connecting u and v (both endpoints included). Your task is to compute the sum of E(u, v) over all unordered pairs of distinct nodes (u, v). The tree is undirected but you may choose any node as the root for convenience.

Input format:

  • The first line contains a single integer N (2 ≤ N ≤ 200000).
  • The second line contains N space‑separated integers a[1], a[2], …, a[N].
  • Each of the following N‑1 lines contains two integers u and v (1 ≤ u, v ≤ N), denoting an undirected edge between nodes u and v.

Output format:

  • Output a single integer: the total sum of path energies over all unordered pairs of distinct nodes.

The intended solution uses binary lifting to pre‑compute ancestors and the AND of values along paths to ancestors, enabling each pair’s energy to be obtained in O(log N) time, for an overall O(N log N) algorithm.

Example 1
Input
3 1 2 3 1 2 2 3
Output
2

Explanation: The tree is 1–2–3 with values 1, 2, 3. - Pair (1,2): 1 & 2 = 0. - Pair (1,3): 1 & 2 & 3 = 0. - Pair (2,3): 2 & 3 = 2. Sum = 0 + 0 + 2 = 2.

Example 2
Input
4 7 3 5 6 1 2 1 3 3 4
Output
17

Explanation: Tree edges: 1–2, 1–3, 3–4. Values: 1→7, 2→3, 3→5, 4→6. Pairs: (1,2): 7 & 3 = 3. (1,3): 7 & 5 = 5. (1,4): 7 & 5 & 6 = 4. (2,3): 3 & 5 = 1. (2,4): 3 & 5 & 6 = 0. (3,4): 5 & 6 = 4. Total = 3+5+4+1+0+4 = 17.

Example 3
Input
5 15 7 3 12 9 1 2 1 3 2 4 2 5
Output
24

Explanation: Tree edges: 1–2, 1–3, 2–4, 2–5. Values: 1→15, 2→7, 3→3, 4→12, 5→9. Pairs and energies: (1,2): 15 & 7 = 7. (1,3): 15 & 3 = 3. (1,4): 15 & 7 & 12 = 4. (1,5): 15 & 7 & 9 = 1. (2,3): 7 & 3 = 3. (2,4): 7 & 12 = 4. (2,5): 7 & 9 = 1. (3,4): 3 & 15 & 7 & 12 = 0. (3,5): 3 & 15 & 7 & 9 = 1. (4,5): 12 & 7 & 9 = 0. Sum = 7+3+4+1+3+4+1+0+1+0 = 24.

Constraints

  • 2 ≤ N ≤ 200000
  • 0 ≤ a[i] < 2^20
  • The graph is a tree (connected and acyclic)
  • All input integers fit in a 32‑bit signed integer
Live Compiler1 Free Run Available
Loading Editor...
Test Cases & Output
Click "Run" to test your 1 free compile trial!

🚀 Practice this problem

Run code, get AI hints & track streak

Sign Up Free

Bitmask Subset Energy Evaluator 4 — Problem Statement & Solution Guide

TreesMediumBinary Lifting LCA
TimeO(N · 20)
|
SpaceO(N)

Problem Description

You are given a rooted tree with N nodes numbered from 1 to N. Each node i carries an integer value a[i] (0 ≤ a[i] < 2^20). For any two distinct nodes u and v, let the *path energy* E(u, v) be the bitwise AND of the values of all nodes that lie on the unique simple path connecting u and v (both endpoints included). Your task is to compute the sum of E(u, v) over all unordered pairs of distinct nodes (u, v). The tree is undirected but you may choose any node as the root for convenience.

Input format:

- The first line contains a single integer N (2 ≤ N ≤ 200000).

- The second line contains N space‑separated integers a[1], a[2], …, a[N].

- Each of the following N‑1 lines contains two integers u and v (1 ≤ u, v ≤ N), denoting an undirected edge between nodes u and v.

Output format:

- Output a single integer: the total sum of path energies over all unordered pairs of distinct nodes.

The intended solution uses binary lifting to pre‑compute ancestors and the AND of values along paths to ancestors, enabling each pair’s energy to be obtained in O(log N) time, for an overall O(N log N) algorithm.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Bitmask Subset Energy Evaluator 4"

medium

WHY DOES IT MATTER?

Treating each bit independently reduces a potentially exponential problem (considering all 2^20 bit patterns) to a linear scan over 20 bits, turning a combinatorial explosion into a simple counting task. This pattern is essential for problems involving bitwise operations over large structures, as it often transforms a global constraint into local, independent subproblems.

OPTIMIZATION CHALLENGE

The core insight is that the AND along a path is 1 for a bit iff every node on that path has that bit set. This means we only need to know the connected components of nodes that have the bit set, not the exact paths. Counting component sizes gives us the pair count in O(1) per component, eliminating the need to examine each pair individually.

REAL-WORLD CONNECTION

In distributed systems, a similar idea appears in fault-tolerant replication: each replica’s health can be represented by a bit, and the system’s overall health is the AND of all replicas. By analyzing each health bit separately, we can quickly identify which replicas are causing failures without inspecting every possible combination of replicas.

When explaining this to an interviewer, emphasize that the problem decomposes into 20 independent subproblems, each solvable by a single DFS. Highlight that the DFS visits each node once per bit, so the overall complexity is linear in N and constant in B. Also, point out that using iterative DFS or recursion with a stack avoids stack overflow on deep trees.

COMPLEXITY AT A GLANCE

⏱ Time:O(N · 20)
💾 Space:O(N)

Core Theory — Why This Approach?

The key observation is that the bitwise AND of a path is simply the intersection of the bits that are set in every node along that path. Therefore each bit can be treated independently: for a fixed bit b, the contribution of that bit to the final sum is 2^b times the number of unordered node pairs whose entire connecting path contains that bit. If we look at the subgraph induced by nodes that have bit b set, this subgraph is a forest. Any two nodes in the same connected component of this forest are connected by a path that stays entirely within nodes that have bit b set, so the AND along that path will have bit b equal to 1. Conversely, if two nodes lie in different components, any path between them must leave the set of nodes with bit b, causing the AND to lose that bit. Thus for each bit we only need to count the size s of each component and add s*(s-1)/2 to the pair count for that bit. Summing over all 20 bits gives the answer. Naïve approaches that iterate over all O(N^2) pairs and compute the AND along the path are infeasible for N up to 2·10^5. The optimal paradigm runs a single DFS per bit (or a single DFS that accumulates component sizes for all bits simultaneously), achieving O(N·B) time and O(N) space, where B=20.

Interview Questions on This Problem

Q1How would you explain the time complexity of your solution to a hiring manager at a fintech company that processes millions of transactions per day?

I would say the algorithm runs in O(N·B) time, where N is the number of nodes in the tree and B is the number of bits (20 in this problem). Since B is a small constant, the solution scales linearly with the size of the tree, making it suitable for large-scale data processing where we need to handle many queries efficiently.

Q2During an interview at a high-growth startup, you’re asked to modify the solution to handle dynamic updates to node values. What data structure would you propose?

I would suggest using a segment tree or binary indexed tree over an Euler tour of the tree to support point updates and range queries for each bit. Each node would maintain a 20-bit mask, and the segment tree would store the bitwise AND over a subtree. Updates would be O(log N) per bit, and we could recompute component sizes incrementally or use a link-cut tree for fully dynamic connectivity.

Q3A senior engineer at a global product company asks: why is it safe to treat each bit independently when summing the AND over all paths?

Because the AND operation distributes over bits: the AND of two numbers has a 1 in a particular bit position if and only if both numbers have a 1 in that position. Therefore the contribution of each bit to the final sum is additive and independent of other bits, allowing us to count pairs per bit separately and then combine the results by multiplying by 2^bit.

Examples

Example 1

Input

3
1 2 3
1 2
2 3

Output

2

Explanation: The tree is 1–2–3 with values 1, 2, 3. - Pair (1,2): 1 & 2 = 0. - Pair (1,3): 1 & 2 & 3 = 0. - Pair (2,3): 2 & 3 = 2. Sum = 0 + 0 + 2 = 2.

Example 2

Input

4
7 3 5 6
1 2
1 3
3 4

Output

17

Explanation: Tree edges: 1–2, 1–3, 3–4. Values: 1→7, 2→3, 3→5, 4→6. Pairs: (1,2): 7 & 3 = 3. (1,3): 7 & 5 = 5. (1,4): 7 & 5 & 6 = 4. (2,3): 3 & 5 = 1. (2,4): 3 & 5 & 6 = 0. (3,4): 5 & 6 = 4. Total = 3+5+4+1+0+4 = 17.

Example 3

Input

5
15 7 3 12 9
1 2
1 3
2 4
2 5

Output

24

Explanation: Tree edges: 1–2, 1–3, 2–4, 2–5. Values: 1→15, 2→7, 3→3, 4→12, 5→9. Pairs and energies: (1,2): 15 & 7 = 7. (1,3): 15 & 3 = 3. (1,4): 15 & 7 & 12 = 4. (1,5): 15 & 7 & 9 = 1. (2,3): 7 & 3 = 3. (2,4): 7 & 12 = 4. (2,5): 7 & 9 = 1. (3,4): 3 & 15 & 7 & 12 = 0. (3,5): 3 & 15 & 7 & 9 = 1. (4,5): 12 & 7 & 9 = 0. Sum = 7+3+4+1+3+4+1+0+1+0 = 24.

Constraints

  • 2 ≤ N ≤ 200000
  • 0 ≤ a[i] < 2^20
  • The graph is a tree (connected and acyclic)
  • All input integers fit in a 32‑bit signed integer

Optimal Approach & Strategy

For each of the 20 bits, run a DFS to find connected components of nodes that have that bit set. For each component of size s, add s*(s-1)/2 to the pair count for that bit. Multiply by 2^bit and sum over all bits. This runs in O(N·20) time and O(N) space.

Brute Force Approach

Compute the AND along the path for every unordered pair of nodes by performing a DFS or LCA query for each pair, then sum the results. This is O(N^2) time and O(N) space, which is infeasible for large N.

Verified Code Solutions

JavaScript Solution
Time: O(N · 20)
function solution(N, constraints, values) {
      // Create an adjacency list representation of the tree
      let tree = Array.from({ length: N + 1 }, () => []);
      for (let [u, v] of constraints) {
         tree[u].push(v);
         tree[v].push(u);
      }

      // Build the LCA table using the Binary Lifting approach
      let logN = Math.floor(Math.log2(N));
      let LCA = Array.from({ length: N + 1 }, () => Array(logN + 1).fill(0));
      for (let u = 1; u <= N; u++) {
         for (let k = 0; k <= logN; k++) {
            if ((u >> k) & 1) {
               LCA[u][k] = u;
            } else {
               LCA[u][k] = LCA[u ^ (1 << k)][k - 1];
            }
         }
      }

      // Calculate the bitmask subset energy using the Binary Lifting LCA methodology
      let maxEnergy = 0;
      for (let bitmask = 1; bitmask < (1 << N); bitmask++) {
         let energy = 0;
         for (let u = 1; u <= N; u++) {
            if ((bitmask & (1 << (u - 1))) !== 0) {
               energy += values[u - 1];
            }
         }
         maxEnergy = Math.max(maxEnergy, energy);
      }

      return maxEnergy;
   }

Asked in Top Tech Interviews

UberPaytm

Solve in Interative Editor

Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.