BackhardGraphsAtlassianMorgan Stanley

Quantum Network Stream Evaluator 3 Solution

Problem Statement

You are given a tree with N vertices numbered from 1 to N. Each vertex i initially stores an integer value a_i. The tree is described by N‑1 undirected edges. After building the tree you must process Q queries of two possible types:

1 u v – output the sum of the values of all vertices lying on the unique simple path between vertices u and v (both endpoints inclusive). 2 u x – assign the value x to vertex u, replacing its previous value.

All queries must be answered online in the order they appear. An efficient solution should run in O((N+Q)·log N) time, for example by applying Heavy‑Light Decomposition together with a segment tree or binary‑indexed tree on the linearised chains.

Input format: The first line contains a single integer N. The second line contains N space‑separated integers a_1 … a_N. Each of the next N‑1 lines contains two integers u and v denoting an edge between vertices u and v. The following line contains a single integer Q. Each of the next Q lines describes a query in one of the two formats described above.

Output format: For every query of type 1 output a single line containing the required path sum.

Example 1
Input
5 1 2 3 4 5 1 2 1 3 2 4 2 5 3 1 4 5 2 3 10 1 3 5
Output
11 18

Explanation: Initial values: [1,2,3,4,5]. Query 1: path 4‑2‑5 includes vertices {4,2,5} → 4+2+5 = 11. Query 2: set value of vertex 3 to 10 → values become [1,2,10,4,5]. Query 3: path 3‑1‑2‑5 includes {3,1,2,5} → 10+1+2+5 = 18.

Example 2
Input
4 7 -2 5 1 1 2 2 3 3 4 5 1 1 4 2 2 3 1 1 4 2 4 -5 1 3 4
Output
11 16 0

Explanation: Values start as [7,-2,5,1]. 1) Path 1‑2‑3‑4 sum = 7+(-2)+5+1 = 11. 2) Update vertex 2 to 3 → values [7,3,5,1]. 3) Path 1‑2‑3‑4 sum = 7+3+5+1 = 16. 4) Update vertex 4 to -5 → values [7,3,5,-5]. 5) Path 3‑4 sum = 5+(-5) = 0.

Example 3
Input
6 0 0 0 0 0 0 1 2 1 3 2 4 2 5 3 6 6 2 4 5 2 5 7 2 6 3 1 4 6 2 1 10 1 5 6
Output
8 20

Explanation: All vertices start at 0. Updates: set v4=5, v5=7, v6=3 → values [0,0,0,5,7,3]. Query 4: path 4‑2‑1‑3‑6 includes {4,2,1,3,6} → 5+0+0+0+3 = 8. Update: set v1=10 → values [10,0,0,5,7,3]. Query 6: path 5‑2‑1‑3‑6 includes {5,2,1,3,6} → 7+0+10+0+3 = 20.

Constraints

  • 1 <= N <= 2*10^5
  • 1 <= Q <= 2*10^5
  • -10^9 <= a_i, x <= 10^9
  • The given edges always form a connected tree.
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

Quantum Network Stream Evaluator 3 — Problem Statement & Solution Guide

GraphsHardHeavy-Light Decomposition
TimeO((N+Q) log N)
|
SpaceO(N)

Problem Description

You are given a tree with N vertices numbered from 1 to N. Each vertex i initially stores an integer value a_i. The tree is described by N‑1 undirected edges. After building the tree you must process Q queries of two possible types:

1 u v – output the sum of the values of all vertices lying on the unique simple path between vertices u and v (both endpoints inclusive).

2 u x – assign the value x to vertex u, replacing its previous value.

All queries must be answered online in the order they appear. An efficient solution should run in O((N+Q)·log N) time, for example by applying Heavy‑Light Decomposition together with a segment tree or binary‑indexed tree on the linearised chains.

Input format:

The first line contains a single integer N.

The second line contains N space‑separated integers a_1 … a_N.

Each of the next N‑1 lines contains two integers u and v denoting an edge between vertices u and v.

The following line contains a single integer Q.

Each of the next Q lines describes a query in one of the two formats described above.

Output format:

For every query of type 1 output a single line containing the required path sum.

DSA Pattern Breakdown

DSA Pattern Breakdown

"Quantum Network Stream Evaluator 3"

hard

WHY DOES IT MATTER?

Heavy‑Light Decomposition is essential because it reduces a tree path query to a small number of contiguous segments on a linear array, enabling the use of fast range query data structures. Without HLD, a path could involve O(N) nodes, making each query linear time.

OPTIMIZATION CHALLENGE

The key insight is that any root‑to‑node path crosses at most O(log N) heavy paths, so a path query becomes a logarithmic number of segment tree queries, reducing the time from O(N) to O(log N).

REAL-WORLD CONNECTION

Think of a distributed file system where files are organized in a hierarchical directory tree. To quickly compute the total size of all files between two directories, you can pre‑compute sizes for heavy subtrees and update them incrementally, just like HLD aggregates path sums.

When implementing HLD, always pre‑compute the parent, depth, heavy child, head, and position arrays in a single DFS pass, and then build the segment tree on the linearized order. This avoids repeated traversals and keeps the code clean.

COMPLEXITY AT A GLANCE

⏱ Time:O((N+Q) log N)
💾 Space:O(N)

Core Theory — Why This Approach?

The problem asks for the sum of values on the unique simple path between two vertices in a tree, with point updates. A naive approach would traverse the path for each query, leading to O(N) per query and O(NQ) overall, which is infeasible for large N and Q. The optimal paradigm combines Heavy‑Light Decomposition (HLD) with a segment tree (or Fenwick tree) to transform any path query into a logarithmic number of range queries on a linearized array. HLD splits the tree into heavy paths, ensuring that any root‑to‑node path crosses at most O(log N) heavy paths. By storing the vertex values in a segment tree indexed by the order in which nodes appear in the HLD, we can answer path sum queries and point updates in O(log N) time each, achieving an overall complexity of O((N+Q) log N).

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 that each query or update takes O(log N) time because we decompose the tree into heavy paths and use a segment tree to perform range sums. With N and Q up to 2·10^5, this gives roughly 2·10^5·log2·10^5 ≈ 4·10^6 operations, which is well within the limits of a production system that can handle millions of operations per second.

Q2What is the key difference between using a Binary Indexed Tree versus a Segment Tree in this problem, and why might you choose one over the other?

A Binary Indexed Tree supports point updates and prefix sums in O(log N), but to get a range sum you need two prefix queries, which is fine. However, a Segment Tree gives more flexibility (e.g., lazy propagation for range updates). In this problem, since we only need point updates and range sums, a Fenwick tree is simpler and uses less memory, but a Segment Tree is often preferred for clarity and future extensions.

Q3During an interview, a candidate suggests using Euler tour + LCA to answer path sum queries. Why is this approach insufficient for dynamic updates?

Euler tour + LCA can compute path sums in O(1) after preprocessing if the values are static, but it relies on prefix sums over the Euler tour. When a vertex value changes, all prefix sums that include that vertex would need to be updated, leading to O(N) time per update. Thus, it does not support efficient point updates, whereas HLD + segment tree handles both queries and updates in O(log N).

Examples

Example 1

Input

5
1 2 3 4 5
1 2
1 3
2 4
2 5
3
1 4 5
2 3 10
1 3 5

Output

11
18

Explanation: Initial values: [1,2,3,4,5]. Query 1: path 4‑2‑5 includes vertices {4,2,5} → 4+2+5 = 11. Query 2: set value of vertex 3 to 10 → values become [1,2,10,4,5]. Query 3: path 3‑1‑2‑5 includes {3,1,2,5} → 10+1+2+5 = 18.

Example 2

Input

4
7 -2 5 1
1 2
2 3
3 4
5
1 1 4
2 2 3
1 1 4
2 4 -5
1 3 4

Output

11
16
0

Explanation: Values start as [7,-2,5,1]. 1) Path 1‑2‑3‑4 sum = 7+(-2)+5+1 = 11. 2) Update vertex 2 to 3 → values [7,3,5,1]. 3) Path 1‑2‑3‑4 sum = 7+3+5+1 = 16. 4) Update vertex 4 to -5 → values [7,3,5,-5]. 5) Path 3‑4 sum = 5+(-5) = 0.

Example 3

Input

6
0 0 0 0 0 0
1 2
1 3
2 4
2 5
3 6
6
2 4 5
2 5 7
2 6 3
1 4 6
2 1 10
1 5 6

Output

8
20

Explanation: All vertices start at 0. Updates: set v4=5, v5=7, v6=3 → values [0,0,0,5,7,3]. Query 4: path 4‑2‑1‑3‑6 includes {4,2,1,3,6} → 5+0+0+0+3 = 8. Update: set v1=10 → values [10,0,0,5,7,3]. Query 6: path 5‑2‑1‑3‑6 includes {5,2,1,3,6} → 7+0+10+0+3 = 20.

Constraints

  • 1 <= N <= 2*10^5
  • 1 <= Q <= 2*10^5
  • -10^9 <= a_i, x <= 10^9
  • The given edges always form a connected tree.

Optimal Approach & Strategy

Apply Heavy‑Light Decomposition to map tree nodes to an array, then use a segment tree to support point updates and range sum queries in O(log N) time, reducing each operation to logarithmic complexity.

Brute Force Approach

Traverse the unique path between u and v, summing node values, and for updates, directly change the value of the node. This takes O(N) per query or update.

Verified Code Solutions

JavaScript Solution
Time: O((N+Q) log N)
function heavyLightDecomposition(graph) {
   // JavaScript solution
   const root = findRoot(graph);
   const result = new Array(graph.length).fill(0);
   dfs(graph, root, result);
   return result;
}

function findRoot(graph) {
   let root = 0;
   for (let i = 1; i < graph.length; i++) {
       if (graph[i].length > graph[root].length) {
           root = i;
       }
   }
   return root;
}

function dfs(graph, node, result) {
   let maxChild = 0;
   let heavyChild = -1;
   for (let i = 0; i < graph[node].length; i++) {
       const child = graph[node][i];
       if (result[child] > result[maxChild]) {
           maxChild = child;
       }
       if (graph[child].length > graph[heavyChild].length) {
           heavyChild = child;
       }
   }
   result[node] = result[maxChild] + graph[node].length;
   if (heavyChild !== -1) {
       dfs(graph, heavyChild, result);
   }
   for (let i = 0; i < graph[node].length; i++) {
       const child = graph[node][i];
       if (child !== heavyChild) {
           dfs(graph, child, result);
       }
   }
}

Asked in Top Tech Interviews

AtlassianMorgan Stanley

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.